📄 coclient.cs
字号:
using System;
using System.Collections;
namespace CO_Full_Server
{
public enum Mode : int
{
Authentication,
CreateCharacter,
Staging,
World
}
public struct Stats
{
public int Strength;
public int Vitality;
public int Spirit;
public int Agility;
}
/// <summary>
/// Summary description for COClient.
/// </summary>
public class COClient : object
{
public Cryptographer Crypto;
public string Account;
public System.Net.Sockets.Socket Sock;
public uint MessageID;
public Mode Status;
public int AccountStatus;
public XYNetSocketLib.XYNetServer GameServer;
public Character[] StagingChars;
public Queue m_InPacketQueue = new Queue(1500, 1.5f);
public Character Char;
public ChatRoom Room;
public COClient()
{
Crypto = new Cryptographer();
//
// TODO: Add constructor logic here
//
}
public void IncomingPacket(byte [] Incoming)
{
System.Threading.Monitor.Enter(Crypto);
System.Threading.Monitor.Enter(m_InPacketQueue);
try
{
byte[] Outgoing;
Console.WriteLine("COClient - Interpreting packet");
Crypto.Decrypt(ref Incoming);
foreach (byte D in Incoming)
{
m_InPacketQueue.Enqueue(D);
}
int z = (byte)m_InPacketQueue.Peek();
while (z <= m_InPacketQueue.Count && z > 0)
{
Incoming = new byte[z];
if (m_InPacketQueue.Count >= z)
{
for (int y = 0; y < z; y++)
{
Incoming[y] = (byte)m_InPacketQueue.Dequeue();
}
}
if (Incoming.Length == 0x1c)
{
#region f2 03
if (Incoming[0x02] == 0xf2 && Incoming[0x03] == 0x03)
{
#region f2 03 type 89
if (Incoming[0x18] == 0x89 && Status == Mode.Staging)
{
Console.WriteLine("Got f2 03 type 89 packet");
//Reply to the first 89 packet
SendData(PacketBuilder.The89());
//Send the a4 packet
SendData(PacketBuilder.TheA4());
//Send the 5604 packet
SendData(PacketBuilder.The5604());
//Send the stamina
SendData(PacketBuilder.TheStamina());
SendData(PacketBuilder.MiniMap(true));
Status = Mode.Staging;
//The client should be ready to receive other people
StagingChars = BackendDB.GetChars(Account);
int Level = 1;
double Rads = 0;
double RadsStep = 0;
int LevelMod = 3;
int LevelCount = 0;
int CurrentLvlMax = 3;
int Count = 0;
double MaxRads = Math.PI * 5 / 4;
double Offset = -3 * Math.PI / 8;
double LengthOffset = 1;
double LengthPerLvl = 2;
Location CurrentLoc;
while (Count < StagingChars.Length)
{
RadsStep = MaxRads / (CurrentLvlMax + 1);
Rads = RadsStep;
while (LevelCount < CurrentLvlMax && Count < StagingChars.Length) //Build the level
{
CurrentLoc.X = (int)(-((LengthOffset + (LengthPerLvl * Level)) * Math.Cos(Rads + Offset)) + World.StagingLoc.X);
CurrentLoc.Y = (int)(-((LengthOffset + (LengthPerLvl * Level)) * Math.Sin(Rads + Offset)) + World.StagingLoc.Y);
StagingChars[Count].CurrentLoc = CurrentLoc;
StagingChars[Count].CharID += 0x00120000;
Outgoing = PacketBuilder.SpawnEntity(StagingChars[Count]);
Crypto.Encrypt(ref Outgoing);
Sock.Send(Outgoing);
Rads += RadsStep;
LevelCount++;
Count++;
}
LevelCount = 0;
CurrentLvlMax += LevelMod;
Level++;
}
//Set the PK mode to PK for character selection
SendData(PacketBuilder.SetPKMode(0, 1187159, PKMode.PK));
}
else if (Incoming[0x18] == 0x89 && Status == Mode.World)
{
#if DEBUG
Console.WriteLine("Got f2 03 type 89 packet");
#endif
//Reply to the first 89 packet
SendData(PacketBuilder.The89(Char));
//Send the a4 packet
SendData(PacketBuilder.TheA4(Char));
//Send the 5604 packet
SendData(PacketBuilder.The5604(Char));
//Send the stamina
SendData(PacketBuilder.TheStamina());
World.GetSurroundings(this);
SendData(PacketBuilder.MiniMap(true));
}
#endregion
else if (Incoming[0x18] == 0x8a)
{
//Reply to the 8a packet
SendData(PacketBuilder.The8A());
}
else if (Incoming[0x18] == 0x8e) //Jump packet
{
if (Status == Mode.World)
{
try
{
World.Jump(this, Incoming);
}
catch
{
throw;
}
}
}
else if (Incoming[0x18] == 0x7e || Incoming[0x18] == 0x7c)
{
World.SendMessageLocal(this, Incoming);
}
else
{
#if DEBUG
foreach (byte D in Incoming)
{
Console.Write((Convert.ToString(D, 16)).PadLeft(2, '0') + " ");
}
Console.WriteLine();
#endif
}
}
#endregion
if (Incoming[0x02] == 0xfe && Incoming[0x03] == 0x03 && Incoming[0x18] == 0x00 && Incoming[0x19] == 0x00)
{
if (Status == Mode.World)
{
//World.SendMessageLocal(this, Incoming);
World.AttackEntity(this, Incoming);
//TODO: write the attack stuff
}
if (Status == Mode.Staging) //Parse the attack packet for the character to load
{
//c d e f
uint Target = 0;
bool HasChar = false;
Target = Incoming[0x0f];
Target = (Target << 8) | Incoming[0x0e];
Target = (Target << 8) | Incoming[0x0d];
Target = (Target << 8) | Incoming[0x0c];
foreach (Character Possible in StagingChars)
{
if (Possible.CharID == Target)
{
HasChar = true;
break;
}
}
if (HasChar != true)
{
throw new Exception("False character selection!");
}
if (World.ClientHash.Contains(Target))
{
World.DropClient(((COClient)(World.ClientHash[Target])), "Client logged on from another location.");
((COClient)(World.ClientHash[Target])).Sock.Shutdown(System.Net.Sockets.SocketShutdown.Send);
}
Char = BackendDB.GetFullChar((uint)(Target - 0x00120000));
Char.CharID += 0x00120000;
foreach (Character Possible in StagingChars)
{
SendData(PacketBuilder.RemoveEntity(Possible.CharID));
}
SendData(PacketBuilder.CharacterInfo(Char));
SendData(PacketBuilder.SetPKMode(PKMode.Peace));
World.ClientHash.Add(Char.CharID, this);
World.SpawnCharacter(this);
Status = Mode.World;
}
}
}
else if (Incoming.Length == 0x0c)
{
if (Incoming[0x02] == 0xed && Incoming[0x03] == 0x03 && Status == Mode.World)
World.Walk(this, Incoming);
}
else if (Incoming.Length == 0x3c)
{
if (Incoming[0x02] == 0xe9 && Incoming[0x03] == 0x03) //Create character packet
{
uint Mesh = 0;
uint Class = 0;
string CharName = "";
Mesh = (uint)Incoming[0x35];
Mesh = (Mesh << 8) | (uint)(Incoming[0x34]);
Class = (uint)Incoming[0x36];
int x = 0x14;
while (x < 0x24 && Incoming[x] != 0x00)
{
CharName += Convert.ToChar(Incoming[x]);
x++;
}
if (!ValidName(CharName) && ((AccountStatus & 0x08) == 0))
{
byte [] Reply = PacketBuilder.InvalidCharacterName(MessageID);
Crypto.Encrypt(ref Reply);
Sock.Send(Reply);
}
else if (BackendDB.CharExists(CharName))
{
byte [] Reply = PacketBuilder.NameTaken(MessageID);
Crypto.Encrypt(ref Reply);
Sock.Send(Reply);
}
else
{
if (BackendDB.CreateCharacter(CharName, Mesh, Class, Account))
{
byte [] Reply = PacketBuilder.CharacterCreated(MessageID);
Crypto.Encrypt(ref Reply);
Sock.Send(Reply);
int Port = 0;
string Address = "";
Address = Sock.RemoteEndPoint.ToString().Split(new char[1]{':'})[0];
Port = Convert.ToInt32(Sock.RemoteEndPoint.ToString().Split(new char[1]{':'})[1]);
GameServer.DropClient(Address, Port);
}
}
}
}
else if (Incoming.Length == 0x14)
{
if (Incoming[0x02] == 0xf1 && Incoming[0x03] == 0x03 && Incoming[0x0c] == 0x1b) //Ping packet
{
Crypto.Encrypt(ref Incoming);
Sock.Send(Incoming);
}
}
else
{
#if DEBUG
foreach (byte D in Incoming)
{
Console.Write((Convert.ToString(D, 16)).PadLeft(2, '0') + " ");
}
Console.WriteLine();
#endif
}
if (Incoming[0x02] == 0xec && Incoming[0x03] == 0x03 && Status == Mode.World) //Chat packet
{
//TODO: Implement chatting
World.Chat(this, Incoming);
}
if (m_InPacketQueue.Count > 0)
z = (byte)m_InPacketQueue.Peek();
else
z = 0;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
System.Threading.Monitor.Exit(m_InPacketQueue);
System.Threading.Monitor.Exit(Crypto);
}
}
private bool ValidName(string Name)
{
if (Name.IndexOfAny(new char[3]{' ', '[', ']'}) > -1)
{
return false;
}
else
{
return true;
}
}
public void SendData(byte[] Data)
{
byte [] Sender = new byte[Data.Length];
Data.CopyTo(Sender, 0);
System.Threading.Monitor.TryEnter(this, new TimeSpan(0, 0, 0, 8, 0));
Crypto.Encrypt(ref Sender);
Sock.Send(Sender);
System.Threading.Monitor.Exit(this);
}
public override string ToString()
{
string Stringer = "";
if (Account != null && Account != "")
Stringer += Account;
if (Char != null)
Stringer += " (" + Char.Name + ")";
if (Sock != null)
Stringer += ": " + Sock.RemoteEndPoint.ToString();
else
Stringer += ": Dead";
return Stringer;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -