source
Created by: Andrew
This commit is contained in:
17
.gitattributes
vendored
Normal file
17
.gitattributes
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
174
.gitignore
vendored
Normal file
174
.gitignore
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding addin-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages/
|
||||
## TODO: If the tool you use requires repositories.config uncomment the next line
|
||||
#!packages/repositories.config
|
||||
|
||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||
# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
|
||||
!packages/build/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
339
LICENSE
Normal file
339
LICENSE
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{description}
|
||||
Copyright (C) {year} {fullname}
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
12
add loopback.bat
Normal file
12
add loopback.bat
Normal file
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
rem Loginservers
|
||||
netsh int ip add addr 1 address=64.94.106.161 mask=255.255.255.255 st=ac
|
||||
netsh int ip add addr 1 address=64.94.106.162 mask=255.255.255.255 st=ac
|
||||
netsh int ip add addr 1 address=64.94.106.163 mask=255.255.255.255 st=ac
|
||||
netsh int ip add addr 1 address=64.94.106.164 mask=255.255.255.255 st=ac
|
||||
netsh int ip add addr 1 address=64.94.106.165 mask=255.255.255.255 st=ac
|
||||
|
||||
rem Webserver
|
||||
netsh int ip add addr 1 address=63.251.217.214 mask=255.255.255.255 st=ac
|
||||
|
||||
pause
|
||||
75
trunk/Common/Common.csproj
Normal file
75
trunk/Common/Common.csproj
Normal file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F163DAAB-BDD2-4510-9A20-604D73D334D0}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>KartExtreme</RootNamespace>
|
||||
<AssemblyName>Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="MySql.Data">
|
||||
<HintPath>..\..\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Data\Database.cs" />
|
||||
<Compile Include="Data\Datum.cs" />
|
||||
<Compile Include="Data\Meta.cs" />
|
||||
<Compile Include="Data\RowNotUniqueException.cs" />
|
||||
<Compile Include="IO\Packet\InPacket.cs" />
|
||||
<Compile Include="IO\Log.cs" />
|
||||
<Compile Include="IO\Packet\OutPacket.cs" />
|
||||
<Compile Include="IO\Packet\PacketReadException.cs" />
|
||||
<Compile Include="IO\SettingReadException.cs" />
|
||||
<Compile Include="IO\Settings.cs" />
|
||||
<Compile Include="Net\Acceptor.cs" />
|
||||
<Compile Include="IO\Packet\PacketBase.cs" />
|
||||
<Compile Include="Net\Cryptography.cs" />
|
||||
<Compile Include="Net\SendPacketException.cs" />
|
||||
<Compile Include="Net\Session.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
19
trunk/Common/Constants.cs
Normal file
19
trunk/Common/Constants.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace KartExtreme
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public static readonly Version Version = new Version()
|
||||
{
|
||||
Localisation = 5002,
|
||||
Major = 1,
|
||||
Minor = 26
|
||||
};
|
||||
}
|
||||
|
||||
public struct Version
|
||||
{
|
||||
public short Localisation { get; set; }
|
||||
public short Major { get; set; }
|
||||
public short Minor { get; set; }
|
||||
}
|
||||
}
|
||||
206
trunk/Common/Data/Database.cs
Normal file
206
trunk/Common/Data/Database.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using KartExtreme.IO;
|
||||
|
||||
namespace KartExtreme.Data
|
||||
{
|
||||
public class TemporaryConnection : IDisposable
|
||||
{
|
||||
private string oldHost;
|
||||
private string oldSchema;
|
||||
private string oldUsername;
|
||||
private string oldPassword;
|
||||
|
||||
internal TemporaryConnection(string host, string schema, string username, string password)
|
||||
{
|
||||
this.oldHost = Database.Host;
|
||||
this.oldSchema = Database.Schema;
|
||||
this.oldUsername = Database.Username;
|
||||
this.oldPassword = Database.Password;
|
||||
|
||||
Database.Host = host;
|
||||
Database.Schema = schema;
|
||||
Database.Username = username;
|
||||
Database.Password = password;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Database.Host = this.oldHost;
|
||||
Database.Schema = this.oldSchema;
|
||||
Database.Username = this.oldUsername;
|
||||
Database.Password = this.oldPassword;
|
||||
}
|
||||
}
|
||||
|
||||
public class TemporarySchema : IDisposable
|
||||
{
|
||||
private string oldSchema;
|
||||
|
||||
internal TemporarySchema(string schema)
|
||||
{
|
||||
this.oldSchema = Database.Schema;
|
||||
Database.Schema = schema;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Database.Schema = this.oldSchema;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Database
|
||||
{
|
||||
public static string Host { get; set; }
|
||||
public static string Schema { get; set; }
|
||||
public static string Username { get; set; }
|
||||
public static string Password { get; set; }
|
||||
|
||||
internal static string CorrectFields(string fields)
|
||||
{
|
||||
string final = string.Empty;
|
||||
string[] tokens = fields.Replace(",", " ").Replace(";", " ").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int processed = 0;
|
||||
|
||||
foreach (string field in tokens)
|
||||
{
|
||||
final += field;
|
||||
processed++;
|
||||
|
||||
if (processed < tokens.Length)
|
||||
{
|
||||
final += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
internal static string ConnectionString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("server={0}; database={1}; uid={2}; password={3}; convertzerodatetime=yes;",
|
||||
Database.Host,
|
||||
Database.Schema,
|
||||
Database.Username,
|
||||
Database.Password);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Execute(string nonQuery, params object[] args)
|
||||
{
|
||||
MySqlHelper.ExecuteNonQuery(Database.ConnectionString, string.Format(nonQuery, args));
|
||||
}
|
||||
|
||||
public static string DefaultSchema
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = Assembly.GetEntryAssembly().GetName().Name;
|
||||
|
||||
switch (name)
|
||||
{
|
||||
case "WvsCenter":
|
||||
return "wvsmaple-center";
|
||||
|
||||
case "WvsLogin":
|
||||
return "wvsmaple-login";
|
||||
|
||||
default:
|
||||
return "wvsmaple-game";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Test()
|
||||
{
|
||||
using (MySqlConnection connection = new MySqlConnection(Database.ConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
Log.Inform("Able to connect to database '{0}'.", connection.Database);
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Analyze()
|
||||
{
|
||||
using (Database.TemporarySchema("information_schema"))
|
||||
{
|
||||
Meta.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(string table, string constraints, params object[] args)
|
||||
{
|
||||
Database.Execute("DELETE FROM {0} WHERE {1}", table, string.Format(constraints, args));
|
||||
}
|
||||
|
||||
public static bool Exists(string table, string constraints, params object[] args)
|
||||
{
|
||||
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, string.Format("SELECT * FROM {0} WHERE {1}", table, string.Format(constraints, args))))
|
||||
{
|
||||
return reader.HasRows;
|
||||
}
|
||||
}
|
||||
|
||||
public static dynamic Fetch(string table, string field, string constraints, params object[] args)
|
||||
{
|
||||
object value = new Datum(table).PopulateWith(field, constraints, args).Dictionary[field];
|
||||
|
||||
if (value is DBNull)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (value is byte && Meta.IsBool(table, field))
|
||||
{
|
||||
return (byte)value > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteScript(string host, string username, string password, string query, params object[] args)
|
||||
{
|
||||
using (MySqlConnection connection = new MySqlConnection(string.Format("SERVER={0}; UID={1}; PASSWORD={2};", host, username, password)))
|
||||
{
|
||||
connection.Open();
|
||||
new MySqlScript(connection, string.Format(query, args)).Execute();
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteFile(string host, string username, string password, string path)
|
||||
{
|
||||
using (MySqlConnection connection = new MySqlConnection(string.Format("SERVER={0}; UID={1}; PASSWORD={2};", host, username, password)))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
using (TextReader reader = new StreamReader(path))
|
||||
{
|
||||
new MySqlScript(connection, reader.ReadToEnd()).Execute();
|
||||
}
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static TemporaryConnection TemporaryConnection(string host, string schema, string username, string password)
|
||||
{
|
||||
return new TemporaryConnection(host, schema, username, password);
|
||||
}
|
||||
|
||||
public static TemporarySchema TemporarySchema(string schema)
|
||||
{
|
||||
return new TemporarySchema(schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
307
trunk/Common/Data/Datum.cs
Normal file
307
trunk/Common/Data/Datum.cs
Normal file
@@ -0,0 +1,307 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Dynamic;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace KartExtreme.Data
|
||||
{
|
||||
public class Datums : IEnumerable<Datum>
|
||||
{
|
||||
private List<Datum> Values { get; set; }
|
||||
private string Table { get; set; }
|
||||
|
||||
public Datums(string table = null)
|
||||
{
|
||||
this.Table = table;
|
||||
}
|
||||
|
||||
internal void PopulateInternal(string fields, string constraints)
|
||||
{
|
||||
this.Values = new List<Datum>();
|
||||
|
||||
string query = string.Format("SELECT {0} FROM {1}{2}", fields == null ? "*" : Database.CorrectFields(fields), this.Table, constraints != null ? " WHERE " + constraints : string.Empty);
|
||||
|
||||
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Dictionary<string, object> dictionary = new Dictionary<string, object>();
|
||||
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
{
|
||||
dictionary.Add(reader.GetName(i), reader.GetValue(i));
|
||||
}
|
||||
|
||||
this.Values.Add(new Datum(this.Table, dictionary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void PopulateInternalFree(string query)
|
||||
{
|
||||
this.Values = new List<Datum>();
|
||||
|
||||
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Dictionary<string, object> dictionary = new Dictionary<string, object>();
|
||||
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
{
|
||||
dictionary.Add(reader.GetName(i), reader.GetValue(i));
|
||||
}
|
||||
|
||||
this.Values.Add(new Datum(this.Table, dictionary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public dynamic Populate()
|
||||
{
|
||||
this.PopulateInternal(null, null);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public dynamic Populate(string constraints, params object[] args)
|
||||
{
|
||||
this.PopulateInternal(null, string.Format(constraints, args));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public dynamic PopulateWith(string fields)
|
||||
{
|
||||
this.PopulateInternal(fields, null);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public dynamic PopulateWith(string fields, string constraints, params object[] args)
|
||||
{
|
||||
this.PopulateInternal(fields, string.Format(constraints, args));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public dynamic PopulateFree(string query)
|
||||
{
|
||||
this.PopulateInternalFree(query);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Datum> GetEnumerator()
|
||||
{
|
||||
foreach (Datum loopDatum in this.Values)
|
||||
{
|
||||
yield return loopDatum;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return (IEnumerator)this.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
public class Datum : DynamicObject
|
||||
{
|
||||
public string Table { get; private set; }
|
||||
|
||||
internal Dictionary<string, object> Dictionary { get; set; }
|
||||
|
||||
public Datum(string table)
|
||||
{
|
||||
this.Table = table;
|
||||
this.Dictionary = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
internal Datum(string table, Dictionary<string, object> values)
|
||||
{
|
||||
this.Table = table;
|
||||
this.Dictionary = values;
|
||||
}
|
||||
|
||||
internal void Populate(string query)
|
||||
{
|
||||
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
|
||||
{
|
||||
if (reader.RecordsAffected > 1)
|
||||
{
|
||||
throw new RowNotUniqueException();
|
||||
}
|
||||
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
throw new RowNotInTableException();
|
||||
}
|
||||
|
||||
reader.Read();
|
||||
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
{
|
||||
string name = reader.GetName(i);
|
||||
object value = reader.GetValue(i);
|
||||
|
||||
if (this.Dictionary.ContainsKey(name))
|
||||
{
|
||||
this.Dictionary[name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Dictionary.Add(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public dynamic Populate(string constraints, params object[] args)
|
||||
{
|
||||
this.Populate(string.Format("SELECT * FROM {0} WHERE {1}", this.Table, string.Format(constraints, args)));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public dynamic PopulateWith(string fields, string constraints, params object[] args)
|
||||
{
|
||||
this.Populate(string.Format("SELECT {0} FROM {1} WHERE {2}", Database.CorrectFields(fields), this.Table, string.Format(constraints, args)));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Insert()
|
||||
{
|
||||
string fields = "( ";
|
||||
|
||||
int processed = 0;
|
||||
|
||||
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
|
||||
{
|
||||
fields += loopPair.Key;
|
||||
processed++;
|
||||
|
||||
if (processed < this.Dictionary.Count)
|
||||
{
|
||||
fields += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
fields += " ) VALUES ( ";
|
||||
|
||||
processed = 0;
|
||||
|
||||
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
|
||||
{
|
||||
fields += string.Format("'{0}'", loopPair.Value is bool ? (((bool)loopPair.Value) ? 1 : 0) : loopPair.Value);
|
||||
processed++;
|
||||
|
||||
if (processed < this.Dictionary.Count)
|
||||
{
|
||||
fields += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
fields += " )";
|
||||
|
||||
Database.Execute("INSERT INTO {0} {1}", this.Table, fields);
|
||||
}
|
||||
|
||||
public void Update(string constraints, params object[] args)
|
||||
{
|
||||
int processed = 0;
|
||||
|
||||
string fields = string.Empty;
|
||||
|
||||
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
|
||||
{
|
||||
fields += string.Format("{0}='{1}'", loopPair.Key, loopPair.Value is bool ? (((bool)loopPair.Value) ? 1 : 0) : loopPair.Value);
|
||||
processed++;
|
||||
|
||||
if (processed < this.Dictionary.Count)
|
||||
{
|
||||
fields += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
Database.Execute("UPDATE {0} SET {1} WHERE {2}", this.Table, fields, string.Format(constraints, args));
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
if (this.Dictionary.ContainsKey(binder.Name))
|
||||
{
|
||||
if (this.Dictionary[binder.Name] is DBNull)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else if (this.Dictionary[binder.Name] is byte && Meta.IsBool(this.Table, binder.Name))
|
||||
{
|
||||
result = (byte)this.Dictionary[binder.Name] > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.Dictionary[binder.Name];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = default(object);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
if (value is DateTime)
|
||||
{
|
||||
if (Meta.IsDate(this.Table, binder.Name))
|
||||
{
|
||||
value = ((DateTime)value).ToString("yyyy-MM-dd");
|
||||
}
|
||||
else if (Meta.IsDateTime(this.Table, binder.Name))
|
||||
{
|
||||
value = ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.Dictionary.ContainsKey(binder.Name))
|
||||
{
|
||||
this.Dictionary[binder.Name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Dictionary.Add(binder.Name, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = this.Table + " [ ";
|
||||
|
||||
int processed = 0;
|
||||
|
||||
foreach (KeyValuePair<string, object> value in this.Dictionary)
|
||||
{
|
||||
result += value.Key;
|
||||
processed++;
|
||||
|
||||
if (processed < this.Dictionary.Count)
|
||||
{
|
||||
result += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
result += " ]";
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
trunk/Common/Data/Meta.cs
Normal file
70
trunk/Common/Data/Meta.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KartExtreme.Data
|
||||
{
|
||||
internal static class Meta
|
||||
{
|
||||
public static Dictionary<string, Dictionary<string, Column>> Tables = new Dictionary<string, Dictionary<string, Column>>();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Meta.Tables.Clear();
|
||||
|
||||
foreach (dynamic datum in new Datums("COLUMNS").Populate("TABLE_SCHEMA = '{0}'", Database.DefaultSchema))
|
||||
{
|
||||
Meta.Add(datum);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Add(dynamic datum)
|
||||
{
|
||||
Dictionary<string, Column> table;
|
||||
|
||||
string tableName = datum.TABLE_NAME;
|
||||
|
||||
if (Meta.Tables.ContainsKey(tableName))
|
||||
{
|
||||
table = Meta.Tables[tableName];
|
||||
}
|
||||
else
|
||||
{
|
||||
table = new Dictionary<string, Column>();
|
||||
Meta.Tables.Add(tableName, table);
|
||||
}
|
||||
|
||||
table.Add(datum.COLUMN_NAME, new Column(datum));
|
||||
}
|
||||
|
||||
public static bool IsBool(String tableName, String fieldName)
|
||||
{
|
||||
return Meta.Tables[tableName][fieldName].ColumnType == "tinyint(1) unsigned";
|
||||
}
|
||||
|
||||
public static bool IsDate(String tableName, String fieldName)
|
||||
{
|
||||
return Meta.Tables[tableName][fieldName].ColumnType == "date";
|
||||
}
|
||||
|
||||
public static bool IsDateTime(String tableName, String fieldName)
|
||||
{
|
||||
return Meta.Tables[tableName][fieldName].ColumnType == "datetime";
|
||||
}
|
||||
}
|
||||
|
||||
internal class Column
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public bool IsPrimaryKey { get; private set; }
|
||||
public bool IsUniqueKey { get; private set; }
|
||||
public string ColumnType { get; private set; }
|
||||
|
||||
public Column(dynamic datum)
|
||||
{
|
||||
this.Name = datum.COLUMN_NAME;
|
||||
this.IsPrimaryKey = datum.COLUMN_KEY == "PRI";
|
||||
this.IsUniqueKey = datum.COLUMN_KEY == "UNI";
|
||||
this.ColumnType = datum.COLUMN_TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
trunk/Common/Data/RowNotUniqueException.cs
Normal file
13
trunk/Common/Data/RowNotUniqueException.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace System.Data
|
||||
{
|
||||
public class RowNotUniqueException : DataException
|
||||
{
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Obtained row is not unique.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
trunk/Common/IO/Packet/InPacket.cs
Normal file
151
trunk/Common/IO/Packet/InPacket.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace KartExtreme.IO.Packet
|
||||
{
|
||||
public class InPacket : PacketBase
|
||||
{
|
||||
private readonly byte[] _buffer;
|
||||
private int _index;
|
||||
|
||||
public override int Position
|
||||
{
|
||||
get { return _index; }
|
||||
}
|
||||
public override int Length
|
||||
{
|
||||
get { return _buffer.Length; }
|
||||
}
|
||||
|
||||
public int Available
|
||||
{
|
||||
get
|
||||
{
|
||||
return _buffer.Length - _index;
|
||||
}
|
||||
}
|
||||
|
||||
public InPacket(byte[] packet)
|
||||
{
|
||||
_buffer = packet;
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
private void CheckLength(int length)
|
||||
{
|
||||
if (_index + length > _buffer.Length || length < 0)
|
||||
throw new PacketReadException("Not enough space");
|
||||
}
|
||||
|
||||
public bool ReadBool()
|
||||
{
|
||||
return ReadByte() == 1;
|
||||
}
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
CheckLength(1);
|
||||
return _buffer[_index++];
|
||||
}
|
||||
public sbyte ReadSByte()
|
||||
{
|
||||
return (sbyte)ReadByte();
|
||||
}
|
||||
|
||||
public byte[] ReadBytes(int count)
|
||||
{
|
||||
CheckLength(count);
|
||||
var temp = new byte[count];
|
||||
Buffer.BlockCopy(_buffer, _index, temp, 0, count);
|
||||
_index += count;
|
||||
return temp;
|
||||
}
|
||||
|
||||
public unsafe short ReadShort()
|
||||
{
|
||||
CheckLength(2);
|
||||
|
||||
short value;
|
||||
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
value = *(short*)(ptr + _index);
|
||||
}
|
||||
|
||||
_index += 2;
|
||||
|
||||
return value;
|
||||
}
|
||||
public ushort ReadUShort()
|
||||
{
|
||||
return (ushort)ReadShort();
|
||||
}
|
||||
|
||||
public unsafe int ReadInt()
|
||||
{
|
||||
CheckLength(4);
|
||||
|
||||
int value;
|
||||
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
value = *(int*)(ptr + _index);
|
||||
}
|
||||
|
||||
_index += 4;
|
||||
|
||||
return value;
|
||||
}
|
||||
public uint ReadUInt()
|
||||
{
|
||||
return (uint)ReadInt();
|
||||
}
|
||||
|
||||
public unsafe long ReadLong()
|
||||
{
|
||||
CheckLength(8);
|
||||
|
||||
long value;
|
||||
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
value = *(long*)(ptr + _index);
|
||||
}
|
||||
|
||||
_index += 8;
|
||||
|
||||
return value;
|
||||
}
|
||||
public ulong ReadULong()
|
||||
{
|
||||
return (ulong)ReadLong();
|
||||
}
|
||||
|
||||
public string ReadString(int count)
|
||||
{
|
||||
CheckLength(count);
|
||||
|
||||
char[] final = new char[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
final[i] = (char)ReadByte();
|
||||
}
|
||||
|
||||
return new string(final);
|
||||
}
|
||||
|
||||
public void Skip(int count)
|
||||
{
|
||||
CheckLength(count);
|
||||
_index += count;
|
||||
}
|
||||
|
||||
public override byte[] ToArray()
|
||||
{
|
||||
var final = new byte[_buffer.Length];
|
||||
Buffer.BlockCopy(_buffer, 0, final, 0, _buffer.Length);
|
||||
return final;
|
||||
}
|
||||
}
|
||||
}
|
||||
167
trunk/Common/IO/Packet/OutPacket.cs
Normal file
167
trunk/Common/IO/Packet/OutPacket.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace KartExtreme.IO.Packet
|
||||
{
|
||||
public class OutPacket : PacketBase, IDisposable
|
||||
{
|
||||
private MemoryStream m_stream;
|
||||
private bool m_disposed;
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return (int)m_stream.Position; }
|
||||
}
|
||||
public override int Position
|
||||
{
|
||||
get { return (int)m_stream.Position; }
|
||||
}
|
||||
|
||||
public bool Disposed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_disposed;
|
||||
}
|
||||
}
|
||||
|
||||
public OutPacket(int size = 64)
|
||||
{
|
||||
m_stream = new MemoryStream(size);
|
||||
m_disposed = false;
|
||||
}
|
||||
|
||||
//From LittleEndianByteConverter by Shoftee
|
||||
private void Append(long value, int byteCount)
|
||||
{
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
{
|
||||
m_stream.WriteByte((byte)value);
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBool(bool value)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
WriteByte(value ? (byte)1 : (byte)0);
|
||||
}
|
||||
|
||||
public void WriteByte(byte value = 0)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
m_stream.WriteByte(value);
|
||||
}
|
||||
public void WriteSByte(sbyte value = 0)
|
||||
{
|
||||
WriteByte((byte)value);
|
||||
}
|
||||
|
||||
public void WriteBytes(params byte[] value)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
m_stream.Write(value, 0, value.Length);
|
||||
}
|
||||
|
||||
public void WriteShort(short value = 0)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
Append(value, 2);
|
||||
}
|
||||
public void WriteUShort(ushort value = 0)
|
||||
{
|
||||
WriteShort((short)value);
|
||||
}
|
||||
|
||||
public void WriteInt(int value = 0)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
Append(value, 4);
|
||||
}
|
||||
public void WriteUInt(uint value = 0)
|
||||
{
|
||||
WriteInt((int)value);
|
||||
}
|
||||
|
||||
public void WriteLong(long value = 0)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
Append(value, 8);
|
||||
}
|
||||
public void WriteULong(ulong value = 0)
|
||||
{
|
||||
WriteLong((long)value);
|
||||
}
|
||||
|
||||
public void WriteString(string value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
WriteInt(value.Length);
|
||||
WriteString(value, value.Length);
|
||||
}
|
||||
public void WriteString(string value, int length)
|
||||
{
|
||||
if (value == null ||
|
||||
length < 1 ||
|
||||
length > value.Length)
|
||||
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
var bytes = Encoding.Unicode.GetBytes(value);
|
||||
var i = 0;
|
||||
|
||||
for (; i < value.Length & i < length; i++)
|
||||
{
|
||||
var offset = i * 2;
|
||||
this.WriteByte(bytes[offset]);
|
||||
this.WriteByte(bytes[offset + 1]);
|
||||
}
|
||||
|
||||
for (; i < length; i++)
|
||||
{
|
||||
this.WriteShort();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteHexString(string value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
value = value.Replace(" ", "");
|
||||
|
||||
for (int i = 0; i < value.Length; i += 2)
|
||||
{
|
||||
WriteByte(byte.Parse(value.Substring(i, 2), NumberStyles.HexNumber));
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowIfDisposed()
|
||||
{
|
||||
if (m_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] ToArray()
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return m_stream.ToArray();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_disposed = true;
|
||||
|
||||
if (m_stream != null)
|
||||
m_stream.Dispose();
|
||||
|
||||
m_stream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
trunk/Common/IO/Packet/PacketBase.cs
Normal file
25
trunk/Common/IO/Packet/PacketBase.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace KartExtreme.IO.Packet
|
||||
{
|
||||
public abstract class PacketBase
|
||||
{
|
||||
public abstract int Length { get; }
|
||||
public abstract int Position { get; }
|
||||
|
||||
public abstract byte[] ToArray();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (byte b in this.ToArray())
|
||||
{
|
||||
sb.AppendFormat("{0:X2} ", b);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
trunk/Common/IO/Packet/PacketReadException.cs
Normal file
16
trunk/Common/IO/Packet/PacketReadException.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KartExtreme.IO.Packet
|
||||
{
|
||||
public sealed class PacketReadException : Exception
|
||||
{
|
||||
public PacketReadException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
9
trunk/Common/IO/SettingReadException.cs
Normal file
9
trunk/Common/IO/SettingReadException.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace KartExtreme.IO
|
||||
{
|
||||
public class SettingReadException : Exception
|
||||
{
|
||||
public SettingReadException(string key) : base(string.Format("Failed to read setting '{0}'.", key)) { }
|
||||
}
|
||||
}
|
||||
188
trunk/Common/IO/Settings.cs
Normal file
188
trunk/Common/IO/Settings.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using KartExtreme.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace KartExtreme.IO
|
||||
{
|
||||
public static class Settings
|
||||
{
|
||||
private const string Comment = "#";
|
||||
|
||||
public static string Path { get; private set; }
|
||||
|
||||
private static Dictionary<string, string> Dictionary;
|
||||
|
||||
public static void Initialize(string path = null)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
path = "Configuration.ini";
|
||||
}
|
||||
|
||||
if (Settings.Dictionary != null)
|
||||
{
|
||||
Settings.Dictionary.Clear();
|
||||
}
|
||||
|
||||
Settings.Path = path;
|
||||
Settings.Dictionary = new Dictionary<string, string>();
|
||||
|
||||
string[] array = Settings.Path.Split('\\');
|
||||
string name = array[array.Length - 1];
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException(string.Format("Unable to find configuration file '{0}'.", name));
|
||||
}
|
||||
else
|
||||
{
|
||||
string line;
|
||||
string currentSection = string.Empty;
|
||||
|
||||
using (StreamReader file = new StreamReader(path))
|
||||
{
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
if (line.StartsWith(Settings.Comment))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("[") && line.EndsWith("]"))
|
||||
{
|
||||
currentSection = line.Trim('[', ']');
|
||||
}
|
||||
else if (line.Contains("="))
|
||||
{
|
||||
Settings.Dictionary.Add(string.Format("{0}{1}{2}",
|
||||
currentSection,
|
||||
(currentSection != string.Empty) ? "/" : string.Empty,
|
||||
line.Split('=')[0]),
|
||||
line.Split('=')[1].Split(';')[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database.Host = Settings.GetString("Database/Host");
|
||||
Database.Schema = Settings.GetString("Database/Schema");
|
||||
Database.Username = Settings.GetString("Database/Username");
|
||||
Database.Password = Settings.GetString("Database/Password");
|
||||
}
|
||||
|
||||
public static int GetInt(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return int.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static short GetShort(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return short.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort GetUShort(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ushort.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte GetByte(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return byte.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static sbyte GetSByte(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return sbyte.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetBool(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return bool.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetString(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Settings.Dictionary[string.Format(key, args)];
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static IPAddress GetIPAddress(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Settings.Dictionary[string.Format(key, args)] == "localhost")
|
||||
{
|
||||
return IPAddress.Loopback;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IPAddress.Parse(Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetEnum<T>(string key, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), Settings.Dictionary[string.Format(key, args)]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new SettingReadException(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
294
trunk/Common/IO/lOG.cs
Normal file
294
trunk/Common/IO/lOG.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace KartExtreme.IO
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
private const byte LabelWidth = 11;
|
||||
private static bool Entitled = false;
|
||||
|
||||
public static bool Running { get; private set; }
|
||||
|
||||
public static string Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return new string(' ', Log.LabelWidth);
|
||||
}
|
||||
}
|
||||
|
||||
public static string MaskString(string input, char mask = '*')
|
||||
{
|
||||
return new string(mask, input.Length);
|
||||
}
|
||||
|
||||
static Log()
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.Clear();
|
||||
|
||||
Log.Running = true;
|
||||
}
|
||||
|
||||
public static string Input(string label)
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
Log.WriteItem("Input", ConsoleColor.Cyan, string.Empty);
|
||||
Console.Write(label);
|
||||
return Console.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
public static string Input(string label, string defaultValue)
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
Log.WriteItem("Input", ConsoleColor.Cyan, string.Empty);
|
||||
Console.Write(label);
|
||||
string result = Console.ReadLine();
|
||||
|
||||
if (result == string.Empty)
|
||||
{
|
||||
result = defaultValue;
|
||||
Console.CursorTop--;
|
||||
Console.CursorLeft = Log.Margin.Length + label.Length;
|
||||
|
||||
Console.WriteLine(defaultValue == string.Empty ? "(None)" : result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a labeled item to the output.
|
||||
/// </summary>
|
||||
/// <param name="label">The label</param>
|
||||
/// <param name="labelColor">The label's color</param>
|
||||
/// <param name="value">The text</param>
|
||||
/// <param name="args">Arguments</param>
|
||||
private static void WriteItem(string label, ConsoleColor labelColor, string value, params object[] args)
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(' ', Log.LabelWidth - label.Length - 3);
|
||||
sb.Append("[");
|
||||
sb.Append(label);
|
||||
sb.Append("]");
|
||||
sb.Append(" ");
|
||||
|
||||
label = sb.ToString();
|
||||
value = string.Format(value, args);
|
||||
|
||||
Console.ForegroundColor = labelColor;
|
||||
Console.Write(label);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
bool first = true;
|
||||
|
||||
foreach (string s in value.Split('\n'))
|
||||
{
|
||||
string[] lines = new string[(int)Math.Ceiling((float)s.Length / (float)(Console.BufferWidth - Log.LabelWidth))];
|
||||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (i == lines.Length - 1)
|
||||
{
|
||||
lines[i] = s.Substring((Console.BufferWidth - Log.LabelWidth) * i);
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i] = s.Substring((Console.BufferWidth - Log.LabelWidth) * i, (Console.BufferWidth - Log.LabelWidth));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
Console.Write(Log.Margin);
|
||||
}
|
||||
|
||||
if ((line.Length + Log.LabelWidth) < Console.BufferWidth)
|
||||
{
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
else if ((line.Length + Log.LabelWidth) == Console.BufferWidth)
|
||||
{
|
||||
Console.Write(line);
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SkipLine()
|
||||
{
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public static void Entitle(string value, params object[] args)
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append("\n");
|
||||
|
||||
//for (int i = 0; i < Console.WindowWidth / 2 - value.Length / 2; i++)
|
||||
//{
|
||||
// sb.Append(' ');
|
||||
//}
|
||||
|
||||
sb.Append('\t');
|
||||
|
||||
sb.Append((Log.Entitled ? "" : "") + string.Format(value, args) + '\n');
|
||||
Console.WriteLine(sb.ToString());
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.Title = string.Format(value, args);
|
||||
|
||||
Log.Entitled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inform(string value, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Info", ConsoleColor.White, value, args);
|
||||
}
|
||||
|
||||
public static void Inform(object value)
|
||||
{
|
||||
Log.Inform(value.ToString());
|
||||
}
|
||||
|
||||
public static void Warn(string value, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Warning", ConsoleColor.Yellow, value, args);
|
||||
}
|
||||
|
||||
public static void Warn(object value)
|
||||
{
|
||||
Log.Warn(value.ToString());
|
||||
}
|
||||
|
||||
public static void Error(string value, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Error", ConsoleColor.Red, value, args);
|
||||
}
|
||||
|
||||
public static bool ShowStackTrace { get; set; }
|
||||
|
||||
public static void Error(Exception exception)
|
||||
{
|
||||
Log.WriteItem("Error", ConsoleColor.Red, Log.ShowStackTrace ? exception.ToString() : exception.Message);
|
||||
}
|
||||
|
||||
public static void Error(string label, Exception exception, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Error", ConsoleColor.Red, "{0}\n{1}", string.Format(label, args), Log.ShowStackTrace ? exception.ToString() : exception.Message);
|
||||
}
|
||||
|
||||
public static void Debug(string value, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Debug", ConsoleColor.Green, value, args);
|
||||
}
|
||||
|
||||
public static void Success(object value)
|
||||
{
|
||||
Log.Debug(value.ToString());
|
||||
}
|
||||
|
||||
public static void Sql(string value, params object[] args)
|
||||
{
|
||||
Log.WriteItem("Sql", ConsoleColor.Magenta, value, args);
|
||||
}
|
||||
|
||||
public static void Hex(string label, byte[] value, params object[] args)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(string.Format(label, args));
|
||||
sb.Append('\n');
|
||||
|
||||
if (value == null || value.Length == 0)
|
||||
{
|
||||
sb.Append("(Empty)");
|
||||
}
|
||||
else
|
||||
{
|
||||
int lineSeparation = 0;
|
||||
|
||||
foreach (byte b in value)
|
||||
{
|
||||
if (lineSeparation == 16)
|
||||
{
|
||||
sb.Append('\n');
|
||||
lineSeparation = 0;
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0:X2} ", b);
|
||||
lineSeparation++;
|
||||
}
|
||||
}
|
||||
|
||||
Log.WriteItem("Hex", ConsoleColor.Magenta, sb.ToString());
|
||||
}
|
||||
|
||||
public static void Hex(string label, byte b, params object[] args)
|
||||
{
|
||||
Log.Hex(label, new byte[] { b }, args);
|
||||
}
|
||||
|
||||
public static void Quit()
|
||||
{
|
||||
Log.Running = false;
|
||||
|
||||
Log.Inform("Press any key to quit . . .");
|
||||
|
||||
Console.Read();
|
||||
}
|
||||
|
||||
public static LoadingIndicator Load(string header)
|
||||
{
|
||||
return new LoadingIndicator(header);
|
||||
}
|
||||
}
|
||||
|
||||
public class LoadingIndicator : IDisposable
|
||||
{
|
||||
public static bool ShowTime { get; set; }
|
||||
|
||||
private DateTime LoadStartTime { get; set; }
|
||||
|
||||
internal LoadingIndicator(string header)
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
Console.Write("{0} {1}... ", Log.Margin, header);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (typeof(Log))
|
||||
{
|
||||
if (LoadingIndicator.ShowTime)
|
||||
{
|
||||
Console.WriteLine("({0}ms)", (DateTime.Now - this.LoadStartTime).Milliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
trunk/Common/Net/Acceptor.cs
Normal file
65
trunk/Common/Net/Acceptor.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using KartExtreme.IO;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
public sealed class Acceptor
|
||||
{
|
||||
public const int Backlog = 25;
|
||||
|
||||
public ushort Port { get; private set; }
|
||||
|
||||
private readonly TcpListener m_listener;
|
||||
|
||||
private bool m_disposed;
|
||||
|
||||
public Action<Socket> OnClientAccepted;
|
||||
|
||||
public Acceptor(ushort port) : this(IPAddress.Any, port) { }
|
||||
|
||||
public Acceptor(IPAddress ip, ushort port)
|
||||
{
|
||||
Port = port;
|
||||
m_listener = new TcpListener(IPAddress.Any, port);
|
||||
OnClientAccepted = null;
|
||||
m_disposed = false;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_listener.Start(Backlog);
|
||||
m_listener.BeginAcceptSocket(EndAccept, null);
|
||||
|
||||
Log.Inform("Initialized clients listener on {0}.", this.Port);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void EndAccept(IAsyncResult iar)
|
||||
{
|
||||
if (m_disposed) { return; }
|
||||
|
||||
Socket client = m_listener.EndAcceptSocket(iar);
|
||||
|
||||
if (OnClientAccepted != null)
|
||||
OnClientAccepted(client);
|
||||
|
||||
if (!m_disposed)
|
||||
m_listener.BeginAcceptSocket(EndAccept, null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!m_disposed)
|
||||
{
|
||||
m_disposed = true;
|
||||
m_listener.Server.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
trunk/Common/Net/Cryptography.cs
Normal file
74
trunk/Common/Net/Cryptography.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
class Cryptography
|
||||
{
|
||||
public static uint HashPacket(byte[] pData, uint pKey, bool pEncrypt, uint npacketLength)
|
||||
{
|
||||
uint hash1 = (pKey ^ 0x14B307C8);
|
||||
uint hash2 = (pKey ^ 0x8CBF12AC);
|
||||
uint hash3 = (pKey ^ 0x240397C1);
|
||||
uint hash4 = (pKey ^ 0xF3BD29C0);
|
||||
|
||||
uint checksum = 0;
|
||||
int packetLength = (int)npacketLength;//pData.Length;
|
||||
|
||||
|
||||
Action<int, uint> doHash = (index, hash) =>
|
||||
{
|
||||
pData[index + 0] ^= (byte)(hash & 0xFF);
|
||||
pData[index + 1] ^= (byte)((hash << 8) & 0xFF);
|
||||
pData[index + 2] ^= (byte)((hash << 16) & 0xFF);
|
||||
pData[index + 3] ^= (byte)((hash << 24) & 0xFF);
|
||||
};
|
||||
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < (packetLength >> 4); ++i)
|
||||
{
|
||||
if (pEncrypt)
|
||||
checksum ^= (uint)(BitConverter.ToUInt32(pData, offset + 12) ^ BitConverter.ToUInt32(pData, offset + 8) ^ BitConverter.ToUInt32(pData, offset + 4) ^ BitConverter.ToUInt32(pData, offset + 0));
|
||||
|
||||
doHash(offset + 0, hash1);
|
||||
doHash(offset + 4, hash2);
|
||||
doHash(offset + 8, hash3);
|
||||
doHash(offset + 12, hash4);
|
||||
|
||||
if (!pEncrypt)
|
||||
checksum ^= (uint)(BitConverter.ToUInt32(pData, offset + 12) ^ BitConverter.ToUInt32(pData, offset + 8) ^ BitConverter.ToUInt32(pData, offset + 4) ^ BitConverter.ToUInt32(pData, offset + 0));
|
||||
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
|
||||
i *= 16;
|
||||
int sub = 0;
|
||||
|
||||
///Note: it has a problem with Checksum Calculation
|
||||
while (i < packetLength)
|
||||
{
|
||||
if (pEncrypt) checksum ^= (uint)(pData[i] << sub);
|
||||
pData[i] ^= (byte)(hash1 << (sub * 8));
|
||||
if (!pEncrypt) checksum ^= (uint)(pData[i] << sub);
|
||||
sub++;
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = offset; i < packetLength; i++)
|
||||
{
|
||||
if (pEncrypt) checksum ^= (uint)(pData[i] << sub);
|
||||
pData[i] ^= (byte)(hash1 << (sub * 8));
|
||||
if (!pEncrypt) checksum ^= (uint)(pData[i] << sub);
|
||||
sub++;
|
||||
}*/
|
||||
|
||||
return checksum;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
trunk/Common/Net/SendPacketException.cs
Normal file
12
trunk/Common/Net/SendPacketException.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
public sealed class SendPacketException : Exception
|
||||
{
|
||||
public SendPacketException()
|
||||
: base("Disconnected while sending packet")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
294
trunk/Common/Net/Session.cs
Normal file
294
trunk/Common/Net/Session.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
using KartExtreme.IO;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using KartExtreme.IO.Packet;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
public abstract class Session
|
||||
{
|
||||
private Socket _socket;
|
||||
|
||||
private byte[] _buffer;
|
||||
private int _bufferIndex;
|
||||
|
||||
private bool _header;
|
||||
private bool _connected;
|
||||
|
||||
private string _label;
|
||||
|
||||
private uint riv;
|
||||
private uint siv;
|
||||
|
||||
private object _lock;
|
||||
|
||||
public string Label
|
||||
{
|
||||
get
|
||||
{
|
||||
return _label;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Session class.
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
public Session(Socket socket)
|
||||
{
|
||||
this._socket = socket;
|
||||
this._socket.NoDelay = true;
|
||||
|
||||
this._label = this._socket.RemoteEndPoint.ToString();
|
||||
|
||||
this._connected = true;
|
||||
|
||||
this._lock = new object();
|
||||
|
||||
this.InitiateReceive(4, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiates the receiving mechanism.
|
||||
/// </summary>
|
||||
/// <param name="length">The length of the data</param>
|
||||
/// <param name="header">Indicates if a header is received</param>
|
||||
private void InitiateReceive(uint length, bool header = false)
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._header = header;
|
||||
this._buffer = new byte[length];
|
||||
this._bufferIndex = 0;
|
||||
|
||||
this.BeginReceive();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins to asynchronously receive data from the socket.
|
||||
/// </summary>
|
||||
private void BeginReceive()
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var error = SocketError.Success;
|
||||
|
||||
this._socket.BeginReceive(this._buffer,
|
||||
this._bufferIndex,
|
||||
this._buffer.Length - this._bufferIndex,
|
||||
SocketFlags.None, out error,
|
||||
EndReceive,
|
||||
null);
|
||||
|
||||
if (error != SocketError.Success)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the data from the callback and handles it.
|
||||
/// </summary>
|
||||
/// <param name="iar"></param>
|
||||
private void EndReceive(IAsyncResult iar)
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var error = SocketError.Success;
|
||||
int received = this._socket.EndReceive(iar, out error);
|
||||
|
||||
if (received == 0 || error != SocketError.Success)
|
||||
{
|
||||
this.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
this._bufferIndex += received;
|
||||
|
||||
if (this._bufferIndex == this._buffer.Length)
|
||||
{
|
||||
if (this._header)
|
||||
{
|
||||
uint header = BitConverter.ToUInt32(this._buffer, 0);
|
||||
|
||||
if(riv != 0)
|
||||
header = (riv ^ header ^ 0xF834A608);
|
||||
|
||||
this.InitiateReceive(header, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (riv != 0)
|
||||
{
|
||||
int bufferLength = _buffer.Length - 4;
|
||||
|
||||
uint originalChecksum = (uint)(riv ^ BitConverter.ToUInt32(this._buffer, bufferLength) ^ 0xC9F84A90);
|
||||
|
||||
Array.Resize<byte>(ref this._buffer, bufferLength);
|
||||
|
||||
uint checksum = Cryptography.HashPacket(this._buffer, riv, false, (uint)bufferLength);
|
||||
|
||||
if (originalChecksum != checksum)
|
||||
{
|
||||
Log.Warn("Decrypt Checksum different!");
|
||||
}
|
||||
|
||||
riv += 21446425;
|
||||
|
||||
if (riv == 0)
|
||||
riv = 1;
|
||||
}
|
||||
|
||||
this.OnPacket(new InPacket(this._buffer));
|
||||
this.InitiateReceive(4, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.BeginReceive();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the initial patch data packet to the socket.
|
||||
/// </summary>
|
||||
/// <param name="version">The version's information</param>
|
||||
/// <param name="patchLocation">The patch data URL</param>
|
||||
public void SendPatchData(Version version, string patchLocation)
|
||||
{
|
||||
//Fuck!!!!!
|
||||
Random rnd = new Random();
|
||||
|
||||
uint val_first = 0;//(uint)rnd.Next();
|
||||
uint val_second = 0;//(uint)rnd.Next() ;
|
||||
|
||||
using (OutPacket outPacket = new OutPacket())
|
||||
{
|
||||
outPacket.WriteHexString("80 05 2B 28"); // NOTE: Header. Do not change. Probably typeid() of handler.
|
||||
outPacket.WriteShort(version.Localisation);
|
||||
outPacket.WriteShort(version.Major);
|
||||
outPacket.WriteShort(version.Minor);
|
||||
outPacket.WriteString(patchLocation);
|
||||
outPacket.WriteInt((int)val_first); // NOTE: IV Keys. Should we do random stuffs?
|
||||
outPacket.WriteInt((int)val_second);
|
||||
outPacket.WriteByte(0xE0); // NOTE: Some stuff used on Region / Service Area.
|
||||
outPacket.WriteHexString("03 00 09 03 00 00 03 00 00 00 00 00 83 A3 E5 47 00 00 15 00 0D 00 00 00 03 00 00 00 00 00 65");
|
||||
|
||||
this.Send(outPacket);
|
||||
}
|
||||
|
||||
riv = val_first ^ val_second;
|
||||
siv = val_first ^ val_second;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a KartExtreme.IO.OutPacket array to the socket.
|
||||
/// </summary>
|
||||
/// <param name="outPacket"></param>
|
||||
public void Send(OutPacket outPacket)
|
||||
{
|
||||
this.Send(outPacket.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends data to the socket.
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
public void Send(byte[] buffer)
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
|
||||
byte[] data = new byte[buffer.Length + (siv != 0 ? 8 : 4)];
|
||||
|
||||
if (siv == 0)
|
||||
{
|
||||
Buffer.BlockCopy(BitConverter.GetBytes((int)buffer.Length), 0, data, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint newHash = Cryptography.HashPacket(buffer, siv, true, (uint)buffer.Length);
|
||||
|
||||
// NOTE: Length at beginning.
|
||||
Buffer.BlockCopy(BitConverter.GetBytes((int)(siv ^ (buffer.Length + 4) ^ 0xF834A608)), 0, data, 0, 4);
|
||||
// NOTE: Checksum at end.
|
||||
Buffer.BlockCopy(BitConverter.GetBytes((uint)(siv ^ newHash ^ 0xC9F84A90)), 0, data, data.Length - 4, 4);
|
||||
|
||||
siv += 0x1473F19;
|
||||
|
||||
if (siv == 0)
|
||||
siv = 1;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(buffer, 0, data, 4, buffer.Length);
|
||||
|
||||
this.SendRaw(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendRaw(byte[] data)
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
while (offset < data.Length)
|
||||
{
|
||||
SocketError error = SocketError.Success;
|
||||
int sent = this._socket.Send(data, offset, data.Length - offset, SocketFlags.None, out error);
|
||||
|
||||
if (sent == 0 || error != SocketError.Success)
|
||||
{
|
||||
throw new SendPacketException();
|
||||
}
|
||||
|
||||
offset += sent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the socket.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (!this._connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._socket.Shutdown(SocketShutdown.Both);
|
||||
this._socket.Close();
|
||||
|
||||
this.OnDisconnect();
|
||||
}
|
||||
|
||||
public abstract void OnDisconnect();
|
||||
public abstract void OnPacket(InPacket inPacket);
|
||||
}
|
||||
}
|
||||
36
trunk/Common/Properties/AssemblyInfo.cs
Normal file
36
trunk/Common/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Common")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Common")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("740eb84a-eada-43e8-b6ed-a278afc3b1a1")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
28
trunk/KartExtreme.sln
Normal file
28
trunk/KartExtreme.sln
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KartExtreme", "KartExtreme\KartExtreme.csproj", "{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{F163DAAB-BDD2-4510-9A20-604D73D334D0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F163DAAB-BDD2-4510-9A20-604D73D334D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F163DAAB-BDD2-4510-9A20-604D73D334D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F163DAAB-BDD2-4510-9A20-604D73D334D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F163DAAB-BDD2-4510-9A20-604D73D334D0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
51
trunk/KartExtreme/Application.cs
Normal file
51
trunk/KartExtreme/Application.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using KartExtreme.IO;
|
||||
using KartExtreme.Net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace KartExtreme
|
||||
{
|
||||
internal static class Application
|
||||
{
|
||||
private static bool _isRunning = false;
|
||||
|
||||
[STAThread]
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Log.Entitle("KartExtreme");
|
||||
|
||||
DateTime dt = DateTime.Now;
|
||||
|
||||
try
|
||||
{
|
||||
Server.Initialize();
|
||||
|
||||
Application._isRunning = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
|
||||
if (Application._isRunning)
|
||||
{
|
||||
Log.Inform("Initialized in {0}ms.", (DateTime.Now - dt).TotalMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Inform("Unable to initialize.");
|
||||
}
|
||||
|
||||
Log.SkipLine();
|
||||
|
||||
while (Application._isRunning)
|
||||
{
|
||||
Console.Read();
|
||||
}
|
||||
|
||||
Log.Quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
trunk/KartExtreme/Kart/Player.cs
Normal file
61
trunk/KartExtreme/Kart/Player.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using KartExtreme.Data;
|
||||
using KartExtreme.Net;
|
||||
|
||||
namespace KartExtreme.Kart
|
||||
{
|
||||
public class Player
|
||||
{
|
||||
public KartClient Client { get; private set; }
|
||||
|
||||
public int ID { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public byte Level { get; private set; }
|
||||
public int Lucci { get; private set; }
|
||||
|
||||
private bool Assigned { get; set; }
|
||||
|
||||
public Player(int id = 0, KartClient client = null)
|
||||
{
|
||||
this.ID = id;
|
||||
this.Client = client;
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
foreach (dynamic datum in new Datums("players").Populate("ID = '{0}'", this.ID))
|
||||
{
|
||||
this.Name = datum.Name;
|
||||
this.Level = datum.Level;
|
||||
this.Lucci = datum.Lucci;
|
||||
|
||||
this.Assigned = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
dynamic datum = new Datum("players");
|
||||
|
||||
datum.ID = this.ID;
|
||||
datum.Name = this.Name;
|
||||
datum.Level = this.Level;
|
||||
datum.Lucci = this.Lucci;
|
||||
|
||||
if (this.Assigned)
|
||||
{
|
||||
datum.Update("ID = '{0}'", this.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
datum.Insert();
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
Database.Delete("players", "ID = '{0}'", this.ID);
|
||||
|
||||
this.Assigned = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
trunk/KartExtreme/KartExtreme.csproj
Normal file
70
trunk/KartExtreme/KartExtreme.csproj
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C3521ADE-F5D2-4C53-8F2F-0E40A380AE6F}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>KartExtreme</RootNamespace>
|
||||
<AssemblyName>KartExtreme</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Application.cs" />
|
||||
<Compile Include="Kart\Player.cs" />
|
||||
<Compile Include="Net\KartClient.cs" />
|
||||
<Compile Include="Net\Server.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.csproj">
|
||||
<Project>{f163daab-bdd2-4510-9a20-604d73d334d0}</Project>
|
||||
<Name>Common</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
138
trunk/KartExtreme/Net/KartClient.cs
Normal file
138
trunk/KartExtreme/Net/KartClient.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using KartExtreme.IO;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using KartExtreme.IO.Packet;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
public sealed class KartClient : Session
|
||||
{
|
||||
public KartClient(Socket socket)
|
||||
: base(socket)
|
||||
{
|
||||
this.SendPatchData(Constants.Version, "http://kart.dn.nexoncdn.co.kr/patch");
|
||||
|
||||
/*
|
||||
using (OutPacket outPacket = new OutPacket())
|
||||
{
|
||||
outPacket.WriteHexString("80 05 2B 28"); // NOTE: HEADER. DO NOT CHANGE. PROBABLY typeid() OF HANDLER?
|
||||
// 8
|
||||
outPacket.WriteShort(5002); // Note: Localisation.
|
||||
// 10
|
||||
outPacket.WriteShort(1); // NOTE: Service area/version.
|
||||
// 12
|
||||
outPacket.WriteShort(26); // NOTE: Subversion number? Current = 26. 25 = Incompatible with server, 27 = Close client.
|
||||
// 14
|
||||
outPacket.WriteString("http://kart.dn.nexoncdn.co.kr/patch");
|
||||
// 18
|
||||
|
||||
// outPacket.WriteHexString("81 82 83 84 85 86 87 88");
|
||||
// outPacket.WriteHexString("94 2E F9 A8 E1 4B 13 5D");
|
||||
// outPacket.WriteHexString("01 02 03 04 05 06 07 08");
|
||||
|
||||
outPacket.WriteInt(0x11111111);
|
||||
outPacket.WriteInt(0x22222222);
|
||||
outPacket.WriteByte(0xE0);
|
||||
outPacket.WriteHexString("03 00 09 03 00 00 03 00 00 00 00 00 83 A3 E5 47 00 00 15 00 0D 00 00 00 03 00 00 00 00 00 65");
|
||||
// NOTE: Nothing more needed.
|
||||
|
||||
if (false)
|
||||
{
|
||||
outPacket.WriteHexString("80 05 2B 28"); // NOTE: HEADER. DO NOT CHANGE. PROBABLY typeid() OF HANDLER?
|
||||
outPacket.WriteHexString("EA 00 03 00 95 0B");
|
||||
outPacket.WriteString("");
|
||||
// NOTE: Nothing more needed.
|
||||
|
||||
}
|
||||
|
||||
if (false)
|
||||
{
|
||||
outPacket.WriteHexString("80 05 2B 28 EA 03 03 00 95 0B");
|
||||
outPacket.WriteString("");
|
||||
// NOTE: Nothing more needed.
|
||||
}
|
||||
if (false)
|
||||
{
|
||||
// NOTE: Original (Korean KartRider).
|
||||
outPacket.WriteHexString("80 05 2B 28");
|
||||
outPacket.WriteHexString("EA 03 03 00 95 0B");
|
||||
outPacket.WriteString("http://kart.dn.nexoncdn.co.kr/patch");
|
||||
outPacket.WriteHexString("94 2E F9 A8 E1 4B 13 5D 76 03 00 09 03 00 00 03 00 00 00 00 00 83 A3 E5 47 00 00 15 00 0D 00 00 00 03 00 00 00 00 00 65");
|
||||
}
|
||||
|
||||
this.Send(outPacket);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public override void OnDisconnect()
|
||||
{
|
||||
Log.Inform("Lost connection from {0}.", this.Label);
|
||||
|
||||
Server.RemoveClient(this);
|
||||
}
|
||||
|
||||
public override void OnPacket(InPacket inPacket)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//int typeId = inPacket.ReadInt();
|
||||
//byte wdf = BitConverter.
|
||||
|
||||
Log.Hex("Received Packet ", inPacket.ToArray());
|
||||
//Log.Inform("String val:" + Encoding.Unicode.GetString(inPacket.ToArray()));
|
||||
|
||||
byte typeId = inPacket.ReadByte();
|
||||
byte a2 = inPacket.ReadByte();
|
||||
byte a3 = inPacket.ReadByte();
|
||||
byte a4 = inPacket.ReadByte();
|
||||
|
||||
int header = BitConverter.ToInt32(new byte[] { typeId, a2, a3, a4 }, 0);
|
||||
switch (typeId)
|
||||
{
|
||||
case 0xBA:
|
||||
using (OutPacket oPacket = new OutPacket())
|
||||
{
|
||||
oPacket.WriteInt(header + 1); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
oPacket.WriteInt(0); // header
|
||||
Send(oPacket);
|
||||
//WALAO!
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (SendPacketException)
|
||||
{
|
||||
Log.Error("Client was disconnected while sending packet");
|
||||
Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Exception during packet handling from {0}: {1}", this.Label, e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
trunk/KartExtreme/Net/Server.cs
Normal file
47
trunk/KartExtreme/Net/Server.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using KartExtreme.Data;
|
||||
using KartExtreme.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace KartExtreme.Net
|
||||
{
|
||||
public static class Server
|
||||
{
|
||||
private static Acceptor _acceptor;
|
||||
private static List<KartClient> _clients;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Server._clients = new List<KartClient>();
|
||||
|
||||
Settings.Initialize();
|
||||
|
||||
Database.Test();
|
||||
Database.Analyze();
|
||||
|
||||
Server._acceptor = new Acceptor(Settings.GetUShort("Net/Port"));
|
||||
Server._acceptor.OnClientAccepted = Server.OnClientAccepted;
|
||||
Server._acceptor.Start();
|
||||
}
|
||||
|
||||
private static void OnClientAccepted(Socket socket)
|
||||
{
|
||||
KartClient client = new KartClient(socket);
|
||||
|
||||
Log.Inform("Accepted connection from {0}.", client.Label);
|
||||
|
||||
Server.AddClient(client);
|
||||
}
|
||||
|
||||
public static void AddClient(KartClient client)
|
||||
{
|
||||
Server._clients.Add(client);
|
||||
}
|
||||
|
||||
public static void RemoveClient(KartClient client)
|
||||
{
|
||||
Server._clients.Remove(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
trunk/KartExtreme/Properties/AssemblyInfo.cs
Normal file
36
trunk/KartExtreme/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("KartExtreme")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("KartExtreme")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ae2be92d-a537-4b11-a719-5a6168df11df")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
3
trunk/KartExtreme/app.config
Normal file
3
trunk/KartExtreme/app.config
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
|
||||
Reference in New Issue
Block a user