mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
Server now processes session ids and stores the correct logged in user in the clientconnection object. Reserve character now creates a entry in the db.
This commit is contained in:
parent
c1e214175f
commit
f996f727dc
@ -24,7 +24,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
public BlockingCollection<BasePacket> sendPacketQueue = new BlockingCollection<BasePacket>(100);
|
public BlockingCollection<BasePacket> sendPacketQueue = new BlockingCollection<BasePacket>(100);
|
||||||
|
|
||||||
//Instance Stuff
|
//Instance Stuff
|
||||||
public uint currentSession;
|
public uint currentUserId = 0;
|
||||||
public uint currentAccount;
|
public uint currentAccount;
|
||||||
|
|
||||||
|
|
||||||
@ -43,6 +43,9 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
|
|
||||||
public void flushQueuedSendPackets()
|
public void flushQueuedSendPackets()
|
||||||
{
|
{
|
||||||
|
if (!socket.Connected)
|
||||||
|
return;
|
||||||
|
|
||||||
while (sendPacketQueue.Count > 0)
|
while (sendPacketQueue.Count > 0)
|
||||||
{
|
{
|
||||||
BasePacket packet = sendPacketQueue.Take();
|
BasePacket packet = sendPacketQueue.Take();
|
||||||
@ -55,8 +58,6 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{ Debug.WriteLine("Weird case, socket was d/ced: {0}", e); }
|
{ Debug.WriteLine("Weird case, socket was d/ced: {0}", e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAddress()
|
public String getAddress()
|
||||||
|
@ -13,22 +13,66 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
|
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
public static void reserveCharacter(int accountId, int slot, int serverId, String name)
|
public static uint getUserIdFromSession(String sessionId)
|
||||||
{
|
{
|
||||||
|
uint id = 0;
|
||||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
MySqlCommand cmd = new MySqlCommand("SELECT * FROM ffxiv_sessions WHERE id = @sessionId AND expiration > NOW()", conn);
|
||||||
cmd.Connection = conn;
|
cmd.Parameters.AddWithValue("@sessionId", sessionId);
|
||||||
cmd.CommandText = "INSERT INTO ffxiv_characters2(accountId, slot, serverId, name, charState) VALUES(@accountId, @slot, @serverId, @name, 0)";
|
using (MySqlDataReader Reader = cmd.ExecuteReader())
|
||||||
cmd.Prepare();
|
{
|
||||||
cmd.Parameters.AddWithValue("@accountId", accountId);
|
while (Reader.Read())
|
||||||
cmd.Parameters.AddWithValue("@slot", slot);
|
{
|
||||||
|
id = Reader.GetUInt32("userId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{ Console.WriteLine(e); }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool reserveCharacter(uint userId, uint slot, uint serverId, String name)
|
||||||
|
{
|
||||||
|
bool alreadyExists = false;
|
||||||
|
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
//Check if exists
|
||||||
|
MySqlCommand cmd = new MySqlCommand("SELECT * FROM ffxiv_characters2 WHERE name=@name AND serverId=@serverId", conn);
|
||||||
cmd.Parameters.AddWithValue("@serverId", serverId);
|
cmd.Parameters.AddWithValue("@serverId", serverId);
|
||||||
cmd.Parameters.AddWithValue("@name", name);
|
cmd.Parameters.AddWithValue("@name", name);
|
||||||
cmd.ExecuteNonQuery();
|
using (MySqlDataReader Reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
if (Reader.HasRows)
|
||||||
|
alreadyExists = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Reserve
|
||||||
|
if (!alreadyExists)
|
||||||
|
{
|
||||||
|
MySqlCommand cmd2 = new MySqlCommand();
|
||||||
|
cmd2.Connection = conn;
|
||||||
|
cmd2.CommandText = "INSERT INTO ffxiv_characters2(userId, slot, serverId, name, state) VALUES(@userId, @slot, @serverId, @name, 0)";
|
||||||
|
cmd2.Prepare();
|
||||||
|
cmd2.Parameters.AddWithValue("@userId", userId);
|
||||||
|
cmd2.Parameters.AddWithValue("@slot", slot);
|
||||||
|
cmd2.Parameters.AddWithValue("@serverId", serverId);
|
||||||
|
cmd2.Parameters.AddWithValue("@name", name);
|
||||||
|
cmd2.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
@ -40,9 +84,11 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
conn.Close();
|
conn.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return alreadyExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void makeCharacter(int accountId, String name, Character charaInfo)
|
public static void makeCharacter(uint accountId, String name, Character charaInfo)
|
||||||
{
|
{
|
||||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||||
{
|
{
|
||||||
@ -234,5 +280,6 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
<Reference Include="MySql.Data">
|
<Reference Include="MySql.Data">
|
||||||
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
|
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
@ -49,17 +52,18 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Character.cs" />
|
<Compile Include="dataobjects\Character.cs" />
|
||||||
<Compile Include="ClientConnection.cs" />
|
<Compile Include="ClientConnection.cs" />
|
||||||
<Compile Include="common\Blowfish.cs" />
|
<Compile Include="common\Blowfish.cs" />
|
||||||
<Compile Include="common\IniFile.cs" />
|
<Compile Include="common\IniFile.cs" />
|
||||||
<Compile Include="common\Utils.cs" />
|
<Compile Include="common\Utils.cs" />
|
||||||
<Compile Include="ConfigConstants.cs" />
|
<Compile Include="ConfigConstants.cs" />
|
||||||
<Compile Include="Database.cs" />
|
<Compile Include="Database.cs" />
|
||||||
|
<Compile Include="dataobjects\World.cs" />
|
||||||
<Compile Include="PacketProcessor.cs" />
|
<Compile Include="PacketProcessor.cs" />
|
||||||
<Compile Include="packets\BasePacket.cs" />
|
<Compile Include="packets\BasePacket.cs" />
|
||||||
<Compile Include="packets\CharacterRequestPacket.cs" />
|
|
||||||
<Compile Include="packets\HardCoded_Packets.cs" />
|
<Compile Include="packets\HardCoded_Packets.cs" />
|
||||||
|
<Compile Include="packets\PacketStructs.cs" />
|
||||||
<Compile Include="packets\SubPacket.cs" />
|
<Compile Include="packets\SubPacket.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
@ -117,19 +117,24 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
|
|
||||||
private void ProcessSessionAcknowledgement(ClientConnection client, SubPacket packet)
|
private void ProcessSessionAcknowledgement(ClientConnection client, SubPacket packet)
|
||||||
{
|
{
|
||||||
//String sessionId = Utils.unsafeAsciiBytesToString(packet.data, 0x30);
|
PacketStructs.SessionPacket sessionPacket = PacketStructs.toSessionStruct(packet.data);
|
||||||
//String clientVersion = Utils.unsafeAsciiBytesToString(packet.data, 0x70);
|
String sessionId = sessionPacket.session;
|
||||||
|
String clientVersion = sessionPacket.version;
|
||||||
|
|
||||||
Debug.WriteLine("Got acknowledgment for secure session.");
|
Console.WriteLine("Got acknowledgment for secure session.");
|
||||||
// Debug.WriteLine("SESSION_ID: {0}", sessionId);
|
Console.WriteLine("SESSION ID: {0}", sessionId);
|
||||||
// Debug.WriteLine("CLIENT_VERSION: {0}", clientVersion);
|
Console.WriteLine("CLIENT VERSION: {0}", clientVersion);
|
||||||
|
|
||||||
//Check if got MYSQL Conn
|
uint userId = Database.getUserIdFromSession(sessionId);
|
||||||
|
client.currentUserId = userId;
|
||||||
|
|
||||||
|
if (userId == 0)
|
||||||
|
{
|
||||||
|
client.disconnect();
|
||||||
|
Console.WriteLine("Invalid session, kicking...");
|
||||||
|
}
|
||||||
|
|
||||||
//auto query = string_format("SELECT userId FROM ffxiv_sessions WHERE id = '%s' AND expiration > NOW()", sessionId.c_str());
|
Console.WriteLine("USER ID: {0}", userId);
|
||||||
|
|
||||||
//Console.WriteLine("UserId {0} logged in.", id);
|
|
||||||
BasePacket outgoingPacket = new BasePacket("./packets/loginAck.bin");
|
BasePacket outgoingPacket = new BasePacket("./packets/loginAck.bin");
|
||||||
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
|
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
|
||||||
client.queuePacket(outgoingPacket);
|
client.queuePacket(outgoingPacket);
|
||||||
@ -137,7 +142,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
|
|
||||||
private void ProcessGetCharacters(ClientConnection client, SubPacket packet)
|
private void ProcessGetCharacters(ClientConnection client, SubPacket packet)
|
||||||
{
|
{
|
||||||
Console.WriteLine("{0} => Get characters", client.getAddress());
|
Console.WriteLine("{0} => Get characters", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId);
|
||||||
BasePacket outgoingPacket = new BasePacket("./packets/getCharsPacket.bin");
|
BasePacket outgoingPacket = new BasePacket("./packets/getCharsPacket.bin");
|
||||||
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
|
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
|
||||||
client.queuePacket(outgoingPacket);
|
client.queuePacket(outgoingPacket);
|
||||||
@ -153,7 +158,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
binReader.Close();
|
binReader.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("{0} => Select character id {1}", client.getAddress(), characterId);
|
Console.WriteLine("{0} => Select character id {1}", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId, characterId);
|
||||||
|
|
||||||
String serverIp = "141.117.162.99";
|
String serverIp = "141.117.162.99";
|
||||||
ushort port = 54992;
|
ushort port = 54992;
|
||||||
@ -180,7 +185,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
{
|
{
|
||||||
packet.debugPrintSubPacket();
|
packet.debugPrintSubPacket();
|
||||||
|
|
||||||
CharacterRequestPacket.CharacterRequest charaReq = CharacterRequestPacket.toStruct(packet.data);
|
PacketStructs.CharacterRequestPacket charaReq = PacketStructs.toCharacterRequestStruct(packet.data);
|
||||||
var slot = charaReq.slot;
|
var slot = charaReq.slot;
|
||||||
var code = charaReq.command;
|
var code = charaReq.command;
|
||||||
var name = charaReq.characterName;
|
var name = charaReq.characterName;
|
||||||
@ -189,23 +194,26 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 0x01://Reserve
|
case 0x01://Reserve
|
||||||
//Database.reserveCharacter(0, slot, worldId, name);
|
var alreadyTaken = Database.reserveCharacter(client.currentUserId, slot, worldId, name);
|
||||||
|
|
||||||
|
if (alreadyTaken)
|
||||||
|
{ }
|
||||||
|
|
||||||
//Confirm Reserve
|
//Confirm Reserve
|
||||||
BasePacket confirmReservePacket = new BasePacket("./packets/chara/confirmReserve.bin");
|
BasePacket confirmReservePacket = new BasePacket("./packets/chara/confirmReserve.bin");
|
||||||
BasePacket.encryptPacket(client.blowfish, confirmReservePacket);
|
BasePacket.encryptPacket(client.blowfish, confirmReservePacket);
|
||||||
client.queuePacket(confirmReservePacket);
|
client.queuePacket(confirmReservePacket);
|
||||||
Console.WriteLine("Reserving character \"{0}\"", charaReq.characterName);
|
Console.WriteLine("User {0} => Reserving character \"{1}\"", client.currentUserId, charaReq.characterName);
|
||||||
break;
|
break;
|
||||||
case 0x02://Make
|
case 0x02://Make
|
||||||
Character character = Character.EncodedToCharacter(charaReq.characterInfoEncoded);
|
Character character = Character.EncodedToCharacter(charaReq.characterInfoEncoded);
|
||||||
Database.makeCharacter(0, name, character);
|
Database.makeCharacter(client.currentUserId, name, character);
|
||||||
|
|
||||||
//Confirm
|
//Confirm
|
||||||
BasePacket confirmMakePacket = new BasePacket("./packets/chara/confirmMake.bin");
|
BasePacket confirmMakePacket = new BasePacket("./packets/chara/confirmMake.bin");
|
||||||
BasePacket.encryptPacket(client.blowfish, confirmMakePacket);
|
BasePacket.encryptPacket(client.blowfish, confirmMakePacket);
|
||||||
client.queuePacket(confirmMakePacket);
|
client.queuePacket(confirmMakePacket);
|
||||||
Console.WriteLine("Character created!");
|
Console.WriteLine("User {0} => Character created!", client.currentUserId);
|
||||||
break;
|
break;
|
||||||
case 0x03://Rename
|
case 0x03://Rename
|
||||||
break;
|
break;
|
||||||
@ -216,7 +224,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
BasePacket deleteConfirmPacket = new BasePacket("./packets/chara/confirmDelete.bin");
|
BasePacket deleteConfirmPacket = new BasePacket("./packets/chara/confirmDelete.bin");
|
||||||
BasePacket.encryptPacket(client.blowfish, deleteConfirmPacket);
|
BasePacket.encryptPacket(client.blowfish, deleteConfirmPacket);
|
||||||
client.queuePacket(deleteConfirmPacket);
|
client.queuePacket(deleteConfirmPacket);
|
||||||
Console.WriteLine("Character deleted \"{0}\"", charaReq.characterName);
|
Console.WriteLine("User {0} => Character deleted \"{1}\"", client.currentUserId, charaReq.characterName);
|
||||||
break;
|
break;
|
||||||
case 0x06://Rename Retainer
|
case 0x06://Rename Retainer
|
||||||
break;
|
break;
|
||||||
|
@ -121,7 +121,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("Connection {0}:{1} has disconnected.", (conn.socket.RemoteEndPoint as IPEndPoint).Address, (conn.socket.RemoteEndPoint as IPEndPoint).Port);
|
Console.WriteLine("{0} has disconnected.", conn.currentUserId == 0 ? conn.getAddress() : "User " + conn.currentUserId);
|
||||||
conn.socket.Close();
|
conn.socket.Close();
|
||||||
lock (mConnectionList)
|
lock (mConnectionList)
|
||||||
{
|
{
|
||||||
@ -133,7 +133,7 @@ namespace FFXIVClassic_Lobby_Server
|
|||||||
{
|
{
|
||||||
if (conn.socket != null)
|
if (conn.socket != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Connection @ {0}:{1} has disconnected.", (conn.socket.RemoteEndPoint as IPEndPoint).Address, (conn.socket.RemoteEndPoint as IPEndPoint).Port);
|
Console.WriteLine("Connection @ {0}:{1} has disconnected.", conn.currentUserId == 0 ? conn.getAddress() : "User " + conn.currentUserId);
|
||||||
conn.socket.Close();
|
conn.socket.Close();
|
||||||
lock (mConnectionList)
|
lock (mConnectionList)
|
||||||
{
|
{
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_Lobby_Server.packets
|
|
||||||
{
|
|
||||||
class CharacterRequestPacket
|
|
||||||
{
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public unsafe struct CharacterRequest
|
|
||||||
{
|
|
||||||
public uint sequence;
|
|
||||||
public uint unknown;
|
|
||||||
public uint characterId;
|
|
||||||
public uint unknown2;
|
|
||||||
public byte slot;
|
|
||||||
public byte command;
|
|
||||||
public ushort worldId;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
|
|
||||||
public String characterName;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x190)]
|
|
||||||
public String characterInfoEncoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe CharacterRequest toStruct(byte[] bytes)
|
|
||||||
{
|
|
||||||
fixed (byte* pdata = &bytes[0])
|
|
||||||
{
|
|
||||||
return (CharacterRequest)Marshal.PtrToStructure(new IntPtr(pdata), typeof(CharacterRequest));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
57
FFXIVClassic_Lobby_Server/packets/PacketStructs.cs
Normal file
57
FFXIVClassic_Lobby_Server/packets/PacketStructs.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Lobby_Server.packets
|
||||||
|
{
|
||||||
|
class PacketStructs
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public unsafe struct SessionPacket
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public uint sequence;
|
||||||
|
[FieldOffset(0x50)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
|
||||||
|
public String version;
|
||||||
|
[FieldOffset(0x70)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
|
||||||
|
public String session;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public unsafe struct CharacterRequestPacket
|
||||||
|
{
|
||||||
|
public uint sequence;
|
||||||
|
public uint unknown;
|
||||||
|
public uint characterId;
|
||||||
|
public uint unknown2;
|
||||||
|
public byte slot;
|
||||||
|
public byte command;
|
||||||
|
public ushort worldId;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
|
||||||
|
public String characterName;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x190)]
|
||||||
|
public String characterInfoEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe CharacterRequestPacket toCharacterRequestStruct(byte[] bytes)
|
||||||
|
{
|
||||||
|
fixed (byte* pdata = &bytes[0])
|
||||||
|
{
|
||||||
|
return (CharacterRequestPacket)Marshal.PtrToStructure(new IntPtr(pdata), typeof(CharacterRequestPacket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe SessionPacket toSessionStruct(byte[] bytes)
|
||||||
|
{
|
||||||
|
fixed (byte* pdata = &bytes[0])
|
||||||
|
{
|
||||||
|
return (SessionPacket)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SessionPacket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user