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