Created by: Andrew
This commit is contained in:
Andrew
2016-08-27 22:43:23 -04:00
commit 6d74d5b59e
31 changed files with 3002 additions and 0 deletions

17
.gitattributes vendored Normal file
View 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
View 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
View 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.

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
A KartRider emulator coded in C#
Coded by: Andrew

12
add loopback.bat Normal file
View 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

View 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
View 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; }
}
}

View 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
View 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
View 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;
}
}
}

View File

@@ -0,0 +1,13 @@
namespace System.Data
{
public class RowNotUniqueException : DataException
{
public override string Message
{
get
{
return "Obtained row is not unique.";
}
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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)
{
}
}
}

View 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
View 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
View 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();
}
}
}
}
}

View 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();
}
}
}
}

View 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;
}
}
}

View 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
View 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);
}
}

View 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
View 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

View 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();
}
}
}

View 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;
}
}
}

View 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>

View 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());
}
}
}
}

View 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);
}
}
}

View 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")]

View 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>