mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-23 05:07:47 +00:00
Initial Commit.
This commit is contained in:
commit
46c4c26d01
82 changed files with 70188 additions and 0 deletions
22
FFXIVClassic Map Server.sln
Normal file
22
FFXIVClassic Map Server.sln
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FFXIVClassic Map Server", "FFXIVClassic Map Server\FFXIVClassic Map Server.csproj", "{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
11
FFXIVClassic Map Server/App.config
Normal file
11
FFXIVClassic Map Server/App.config
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data></configuration>
|
74
FFXIVClassic Map Server/ClientConnection.cs
Normal file
74
FFXIVClassic Map Server/ClientConnection.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Sockets;
|
||||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System.Diagnostics;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using Cyotek.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class ClientConnection
|
||||
{
|
||||
//Connection stuff
|
||||
public Blowfish blowfish;
|
||||
public Socket socket;
|
||||
public byte[] buffer = new byte[0xffff];
|
||||
public CircularBuffer<byte> incomingStream = new CircularBuffer<byte>(1024);
|
||||
public BlockingCollection<BasePacket> sendPacketQueue = new BlockingCollection<BasePacket>(100);
|
||||
|
||||
//Instance Stuff
|
||||
public uint owner = 0;
|
||||
public uint connType = 0;
|
||||
|
||||
|
||||
public void processIncoming(int bytesIn)
|
||||
{
|
||||
if (bytesIn == 0)
|
||||
return;
|
||||
|
||||
incomingStream.Put(buffer, 0, bytesIn);
|
||||
}
|
||||
|
||||
public void queuePacket(BasePacket packet)
|
||||
{
|
||||
sendPacketQueue.Add(packet);
|
||||
}
|
||||
|
||||
public void flushQueuedSendPackets()
|
||||
{
|
||||
if (!socket.Connected)
|
||||
return;
|
||||
|
||||
while (sendPacketQueue.Count > 0)
|
||||
{
|
||||
BasePacket packet = sendPacketQueue.Take();
|
||||
byte[] packetBytes = packet.getPacketBytes();
|
||||
byte[] buffer = new byte[0xffff];
|
||||
Array.Copy(packetBytes, buffer, packetBytes.Length);
|
||||
try
|
||||
{
|
||||
socket.Send(packetBytes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{ Log.error(String.Format("Weird case, socket was d/ced: {0}", e)); }
|
||||
}
|
||||
}
|
||||
|
||||
public String getAddress()
|
||||
{
|
||||
return String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port);
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
socket.Disconnect(false);
|
||||
}
|
||||
}
|
||||
}
|
55
FFXIVClassic Map Server/ConfigConstants.cs
Normal file
55
FFXIVClassic Map Server/ConfigConstants.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
using FFXIVClassic_Lobby_Server.common;
|
||||
using STA.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class ConfigConstants
|
||||
{
|
||||
public static String OPTIONS_BINDIP;
|
||||
public static bool OPTIONS_TIMESTAMP = false;
|
||||
|
||||
public static uint DATABASE_WORLDID;
|
||||
public static String DATABASE_HOST;
|
||||
public static String DATABASE_PORT;
|
||||
public static String DATABASE_NAME;
|
||||
public static String DATABASE_USERNAME;
|
||||
public static String DATABASE_PASSWORD;
|
||||
|
||||
public static bool load()
|
||||
{
|
||||
Console.Write("Loading config.ini file... ");
|
||||
|
||||
if (!File.Exists("./config.ini"))
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("[FILE NOT FOUND]");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
return false;
|
||||
}
|
||||
|
||||
INIFile configIni = new INIFile("./config.ini");
|
||||
|
||||
ConfigConstants.OPTIONS_BINDIP = configIni.GetValue("General", "server_ip", "127.0.0.1");
|
||||
ConfigConstants.OPTIONS_TIMESTAMP = configIni.GetValue("General", "showtimestamp", "true").ToLower().Equals("true");
|
||||
|
||||
ConfigConstants.DATABASE_WORLDID = configIni.GetValue("Database", "worldid", (uint)0);
|
||||
ConfigConstants.DATABASE_HOST = configIni.GetValue("Database", "host", "");
|
||||
ConfigConstants.DATABASE_PORT = configIni.GetValue("Database", "port", "");
|
||||
ConfigConstants.DATABASE_NAME = configIni.GetValue("Database", "database", "");
|
||||
ConfigConstants.DATABASE_USERNAME = configIni.GetValue("Database", "username", "");
|
||||
ConfigConstants.DATABASE_PASSWORD = configIni.GetValue("Database", "password", "");
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine("[OK]");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
90
FFXIVClassic Map Server/Database.cs
Normal file
90
FFXIVClassic Map Server/Database.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Dapper;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
|
||||
class Database
|
||||
{
|
||||
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)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT * FROM sessions WHERE id = @sessionId AND expiration > NOW()", conn);
|
||||
cmd.Parameters.AddWithValue("@sessionId", sessionId);
|
||||
using (MySqlDataReader Reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (Reader.Read())
|
||||
{
|
||||
id = Reader.GetUInt32("userId");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{ Console.WriteLine(e); }
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public static World getServer(uint serverId)
|
||||
{
|
||||
using (var 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)))
|
||||
{
|
||||
World world = null;
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
world = conn.Query<World>("SELECT * FROM servers WHERE id=@ServerId", new {ServerId = serverId}).SingleOrDefault();
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
|
||||
return world;
|
||||
}
|
||||
}
|
||||
|
||||
public static Character getCharacter(uint userId, uint charId)
|
||||
{
|
||||
using (var 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)))
|
||||
{
|
||||
Character chara = null;
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
chara = conn.Query<Character>("SELECT * FROM characters WHERE id=@CharaId and userId=@UserId", new { UserId = userId, CharaId = charId }).SingleOrDefault();
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
|
||||
return chara;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
105
FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
Normal file
105
FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?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>{E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>FFXIVClassic_Map_Server</RootNamespace>
|
||||
<AssemblyName>FFXIVClassic Map Server</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Cyotek.Collections.Generic.CircularBuffer">
|
||||
<HintPath>..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Dapper">
|
||||
<HintPath>..\packages\Dapper.1.42\lib\net45\Dapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data">
|
||||
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
|
||||
</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.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="ClientConnection.cs" />
|
||||
<Compile Include="common\Bitfield.cs" />
|
||||
<Compile Include="common\Blowfish.cs" />
|
||||
<Compile Include="common\Log.cs" />
|
||||
<Compile Include="common\STA_INIFile.cs" />
|
||||
<Compile Include="common\Utils.cs" />
|
||||
<Compile Include="ConfigConstants.cs" />
|
||||
<Compile Include="Database.cs" />
|
||||
<Compile Include="dataobjects\Actor.cs" />
|
||||
<Compile Include="dataobjects\Character.cs" />
|
||||
<Compile Include="dataobjects\CharaInfo.cs" />
|
||||
<Compile Include="dataobjects\Player.cs" />
|
||||
<Compile Include="dataobjects\World.cs" />
|
||||
<Compile Include="PacketProcessor.cs" />
|
||||
<Compile Include="packets\BasePacket.cs" />
|
||||
<Compile Include="packets\receive\HandshakePacket.cs" />
|
||||
<Compile Include="packets\send\login\0x2Packet.cs" />
|
||||
<Compile Include="packets\send\Actor\AddActorPacket.cs" />
|
||||
<Compile Include="packets\send\Actor\MoveActorToPositionPacket.cs" />
|
||||
<Compile Include="packets\send\Actor\RemoveActorPacketPacket.cs" />
|
||||
<Compile Include="packets\send\Actor\SetActorAppearancePacket.cs" />
|
||||
<Compile Include="packets\send\Actor\SetActorPositionPacket.cs" />
|
||||
<Compile Include="packets\send\login\InitPacket.cs" />
|
||||
<Compile Include="packets\send\PongPacket.cs" />
|
||||
<Compile Include="packets\send\SetMapPacket.cs" />
|
||||
<Compile Include="packets\send\SetMusicPacket.cs" />
|
||||
<Compile Include="packets\send\SetWeatherPacket.cs" />
|
||||
<Compile Include="packets\SubPacket.cs" />
|
||||
<Compile Include="packets\receive\PingPacket.cs" />
|
||||
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Server.cs" />
|
||||
<Compile Include="UnknownLoginPacket.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<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>
|
226
FFXIVClassic Map Server/PacketProcessor.cs
Normal file
226
FFXIVClassic Map Server/PacketProcessor.cs
Normal file
|
@ -0,0 +1,226 @@
|
|||
using FFXIVClassic_Lobby_Server.common;
|
||||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
using FFXIVClassic_Map_Server.packets.receive;
|
||||
using FFXIVClassic_Map_Server.packets.send;
|
||||
using FFXIVClassic_Map_Server.packets.send.login;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class PacketProcessor
|
||||
{
|
||||
Dictionary<uint, Player> mPlayers = new Dictionary<uint, Player>();
|
||||
List<ClientConnection> mConnections;
|
||||
Boolean isAlive = true;
|
||||
|
||||
public PacketProcessor(List<ClientConnection> connectionList)
|
||||
{
|
||||
mConnections = connectionList;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
Console.WriteLine("Packet processing thread has started");
|
||||
while (isAlive)
|
||||
{
|
||||
lock (mConnections)
|
||||
{
|
||||
foreach (ClientConnection conn in mConnections)
|
||||
{
|
||||
//Receive conn1 packets
|
||||
while (true)
|
||||
{
|
||||
if (conn == null || conn.incomingStream.Size < BasePacket.BASEPACKET_SIZE)
|
||||
break;
|
||||
|
||||
try {
|
||||
if (conn.incomingStream.Size < BasePacket.BASEPACKET_SIZE)
|
||||
break;
|
||||
BasePacketHeader header = BasePacket.getHeader(conn.incomingStream.Peek(BasePacket.BASEPACKET_SIZE));
|
||||
|
||||
if (conn.incomingStream.Size < header.packetSize)
|
||||
break;
|
||||
|
||||
BasePacket packet = new BasePacket(conn.incomingStream.Get(header.packetSize));
|
||||
processPacket(conn, packet);
|
||||
|
||||
}
|
||||
catch(OverflowException)
|
||||
{ break; }
|
||||
}
|
||||
|
||||
//Send packets
|
||||
if (conn != null && conn.sendPacketQueue.Count != 0)
|
||||
conn.flushQueuedSendPackets();
|
||||
}
|
||||
}
|
||||
|
||||
//Don't waste CPU if isn't needed
|
||||
if (mConnections.Count == 0)
|
||||
Thread.Sleep(2000);
|
||||
else
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
private void processPacket(ClientConnection client, BasePacket packet)
|
||||
{
|
||||
Player player = null;
|
||||
if (client.owner != 0 && mPlayers.ContainsKey(client.owner))
|
||||
player = mPlayers[client.owner];
|
||||
|
||||
if (packet.header.isEncrypted == 0x01)
|
||||
BasePacket.decryptPacket(client.blowfish, ref packet);
|
||||
|
||||
|
||||
List<SubPacket> subPackets = packet.getSubpackets();
|
||||
foreach (SubPacket subpacket in subPackets)
|
||||
{
|
||||
//Console.WriteLine(client.getAddress());
|
||||
switch (subpacket.header.opcode)
|
||||
{
|
||||
//Initial
|
||||
case 0x0000:
|
||||
BasePacket init = InitPacket.buildPacket(0, Utils.UnixTimeStampUTC());
|
||||
BasePacket reply2 = new BasePacket("./packets/login2.bin");
|
||||
|
||||
//Already Handshaked
|
||||
if (client.owner != 0)
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(reply2.data))
|
||||
{
|
||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
||||
{
|
||||
binReader.BaseStream.Seek(0x10, SeekOrigin.Begin);
|
||||
binReader.Write(player.actorID);
|
||||
}
|
||||
}
|
||||
|
||||
client.sendPacketQueue.Add(init);
|
||||
client.sendPacketQueue.Add(reply2);
|
||||
break;
|
||||
}
|
||||
|
||||
uint actorID = 0;
|
||||
using (MemoryStream mem = new MemoryStream(packet.data))
|
||||
{
|
||||
using (BinaryReader binReader = new BinaryReader(mem))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] readIn = new byte[12];
|
||||
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
|
||||
binReader.Read(readIn, 0, 12);
|
||||
actorID = UInt32.Parse(Encoding.ASCII.GetString(readIn));
|
||||
}
|
||||
catch (Exception)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
if (actorID == 0)
|
||||
break;
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(reply2.data))
|
||||
{
|
||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
||||
{
|
||||
binReader.BaseStream.Seek(0x10, SeekOrigin.Begin);
|
||||
binReader.Write(actorID);
|
||||
}
|
||||
}
|
||||
|
||||
Log.debug(String.Format("Got actorID {0} for conn {1}.", actorID, client.getAddress()));
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
player = new Player(actorID);
|
||||
mPlayers[actorID] = player;
|
||||
client.owner = actorID;
|
||||
client.connType = 0;
|
||||
player.setConnection1(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.owner = actorID;
|
||||
client.connType = 1;
|
||||
player.setConnection2(client);
|
||||
}
|
||||
|
||||
//Get Character info
|
||||
//Create player actor
|
||||
client.sendPacketQueue.Add(init);
|
||||
client.sendPacketQueue.Add(reply2);
|
||||
break;
|
||||
//Ping
|
||||
case 0x0001:
|
||||
subpacket.debugPrintSubPacket();
|
||||
PingPacket pingPacket = new PingPacket(subpacket.data);
|
||||
client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false));
|
||||
break;
|
||||
//Unknown
|
||||
case 0x0002:
|
||||
subpacket.debugPrintSubPacket();
|
||||
|
||||
BasePacket setMapPacket = BasePacket.createPacket(SetMapPacket.buildPacket(player.actorID, 0xD1), true, false);
|
||||
BasePacket setPlayerActorPacket = BasePacket.createPacket(_0x2Packet.buildPacket(player.actorID), true, false);
|
||||
|
||||
BasePacket reply5 = new BasePacket("./packets/asd/login5.bin");
|
||||
BasePacket reply6 = new BasePacket("./packets/asd/login6_data.bin");
|
||||
BasePacket reply7 = new BasePacket("./packets/asd/login7_data.bin");
|
||||
BasePacket reply8 = new BasePacket("./packets/asd/login8_data.bin");
|
||||
BasePacket reply9 = new BasePacket("./packets/asd/login9_zonesetup.bin");
|
||||
BasePacket reply10 = new BasePacket("./packets/asd/login10.bin");
|
||||
|
||||
|
||||
client.sendPacketQueue.Add(setMapPacket);
|
||||
client.sendPacketQueue.Add(setPlayerActorPacket);
|
||||
client.sendPacketQueue.Add(reply5);
|
||||
client.sendPacketQueue.Add(reply6);
|
||||
client.sendPacketQueue.Add(reply7);
|
||||
client.sendPacketQueue.Add(reply8);
|
||||
client.sendPacketQueue.Add(reply9);
|
||||
//client.sendPacketQueue.Add(reply10);
|
||||
|
||||
break;
|
||||
//Chat Received
|
||||
case 0x0003:
|
||||
subpacket.debugPrintSubPacket();
|
||||
break;
|
||||
//Update Position
|
||||
case 0x00CA:
|
||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||
player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||
break;
|
||||
case 0x00CD:
|
||||
subpacket.debugPrintSubPacket();
|
||||
//ProcessSetSelection(subPacket);
|
||||
break;
|
||||
case 0x012D:
|
||||
subpacket.debugPrintSubPacket();
|
||||
//ProcessScriptCommand(subPacket);
|
||||
break;
|
||||
case 0x012E:
|
||||
subpacket.debugPrintSubPacket();
|
||||
//ProcessScriptResult(subPacket);
|
||||
break;
|
||||
default:
|
||||
Log.debug(String.Format("Unknown command 0x{0:X} received.", subpacket.header.opcode));
|
||||
subpacket.debugPrintSubPacket();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
81
FFXIVClassic Map Server/Program.cs
Normal file
81
FFXIVClassic Map Server/Program.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using System.Runtime.InteropServices;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Reflection;
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class Program
|
||||
{
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
#if DEBUG
|
||||
TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
|
||||
Debug.Listeners.Add(myWriter);
|
||||
#endif
|
||||
|
||||
bool startServer = true;
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("---------FFXIV 1.0 Map Server---------");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
|
||||
Assembly assem = Assembly.GetExecutingAssembly();
|
||||
Version vers = assem.GetName().Version;
|
||||
Console.WriteLine("Version: " + vers.ToString());
|
||||
|
||||
//Load Config
|
||||
if (!ConfigConstants.load())
|
||||
startServer = false;
|
||||
|
||||
//Test DB Connection
|
||||
Console.Write("Testing DB connection... ");
|
||||
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();
|
||||
conn.Close();
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine("[OK]");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("[FAILED]");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
startServer = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Check World ID
|
||||
World thisWorld = Database.getServer(ConfigConstants.DATABASE_WORLDID);
|
||||
if (thisWorld != null)
|
||||
Console.WriteLine("Successfully pulled world info from DB. Server name is {0}.", thisWorld.name);
|
||||
else
|
||||
Console.WriteLine("World info could not be retrieved from the DB. Welcome and MOTD will not be displayed.");
|
||||
|
||||
//Start server if A-OK
|
||||
if (startServer)
|
||||
{
|
||||
Server server = new Server();
|
||||
server.startServer();
|
||||
|
||||
while (true) Thread.Sleep(10000);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press any key to continue...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
36
FFXIVClassic Map Server/Properties/AssemblyInfo.cs
Normal file
36
FFXIVClassic Map Server/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("FFXIVClassic Map Server")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("FFXIVClassic Map Server")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[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("01e76cc8-4442-4a1f-aaa4-fe418e18e34b")]
|
||||
|
||||
// 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")]
|
183
FFXIVClassic Map Server/Server.cs
Normal file
183
FFXIVClassic Map Server/Server.cs
Normal file
|
@ -0,0 +1,183 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class Server
|
||||
{
|
||||
public const int FFXIV_MAP_PORT = 54992;
|
||||
public const int BUFFER_SIZE = 0x400;
|
||||
public const int BACKLOG = 100;
|
||||
|
||||
private Socket mServerSocket;
|
||||
|
||||
private List<Player> mConnectedPlayerList = new List<Player>();
|
||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
||||
private PacketProcessor mProcessor;
|
||||
private Thread mProcessorThread;
|
||||
|
||||
#region Socket Handling
|
||||
public bool startServer()
|
||||
{
|
||||
IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), FFXIV_MAP_PORT);
|
||||
|
||||
try{
|
||||
mServerSocket = new System.Net.Sockets.Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException("Could not create socket, check to make sure not duplicating port", e);
|
||||
}
|
||||
try
|
||||
{
|
||||
mServerSocket.Bind(serverEndPoint);
|
||||
mServerSocket.Listen(BACKLOG);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException("Error occured while binding socket, check inner exception", e);
|
||||
}
|
||||
try
|
||||
{
|
||||
mServerSocket.BeginAccept(new AsyncCallback(acceptCallback), mServerSocket);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException("Error occured starting listeners, check inner exception", e);
|
||||
}
|
||||
|
||||
Console.Write("Game server has started @ ");
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine("{0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
mProcessor = new PacketProcessor(mConnectionList);
|
||||
mProcessorThread = new Thread(new ThreadStart(mProcessor.update));
|
||||
mProcessorThread.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void acceptCallback(IAsyncResult result)
|
||||
{
|
||||
ClientConnection conn = null;
|
||||
Socket socket = (System.Net.Sockets.Socket)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
conn = new ClientConnection();
|
||||
conn.socket = socket.EndAccept(result);
|
||||
conn.buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Add(conn);
|
||||
}
|
||||
|
||||
Log.conn(String.Format("Connection {0}:{1} has connected.", (conn.socket.RemoteEndPoint as IPEndPoint).Address, (conn.socket.RemoteEndPoint as IPEndPoint).Port));
|
||||
//Queue recieving of data from the connection
|
||||
conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn);
|
||||
//Queue the accept of the next incomming connection
|
||||
mServerSocket.BeginAccept(new AsyncCallback(acceptCallback), mServerSocket);
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
}
|
||||
mServerSocket.BeginAccept(new AsyncCallback(acceptCallback), mServerSocket);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
}
|
||||
mServerSocket.BeginAccept(new AsyncCallback(acceptCallback), mServerSocket);
|
||||
}
|
||||
}
|
||||
|
||||
private Player findPlayerBySocket(Socket s)
|
||||
{
|
||||
lock (mConnectedPlayerList)
|
||||
{
|
||||
foreach (Player p in mConnectedPlayerList)
|
||||
{
|
||||
if ((p.getConnection1().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address))
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
if ((p.getConnection2().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address))
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Player findPlayerByClientConnection(ClientConnection conn)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void receiveCallback(IAsyncResult result)
|
||||
{
|
||||
ClientConnection conn = (ClientConnection)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
int bytesRead = conn.socket.EndReceive(result);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
conn.processIncoming(bytesRead);
|
||||
|
||||
//Queue the next receive
|
||||
conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.conn(String.Format("{0} has disconnected.", conn.owner == 0 ? conn.getAddress() : "User " + conn.owner));
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
if (conn.socket != null)
|
||||
{
|
||||
Log.conn(String.Format("{0} has disconnected.", conn.owner == 0 ? conn.getAddress() : "User " + conn.owner));
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
1
FFXIVClassic Map Server/UnknownLoginPacket.cs
Normal file
1
FFXIVClassic Map Server/UnknownLoginPacket.cs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,274 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Cyotek.Collections.Generic.CircularBuffer</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:Cyotek.Collections.Generic.CircularBuffer`1">
|
||||
<summary>
|
||||
Represents a first-in, first-out collection of objects using a fixed buffer and automatic overwrite support.
|
||||
</summary>
|
||||
<typeparam name="T">Specifies the type of elements in the buffer.</typeparam>
|
||||
<remarks>
|
||||
<para>The capacity of a <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is the number of elements the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> can
|
||||
hold. If an attempt is made to put more items in the buffer than available capacity, items at the start of the buffer are
|
||||
automatically overwritten. This behavior can be modified via the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property.</para>
|
||||
<para>CircularBuffer{T} accepts <c>null</c> as a valid value for reference types and allows duplicate elements.</para>
|
||||
<para>The <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Get"/> methods will remove the items that are returned from the CircularBuffer{T}. To view the contents of the CircularBuffer{T} without removing items, use the <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek"/> or <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.PeekLast"/> methods.</para>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.#ctor(System.Int32)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> class that is empty and has the specified initial capacity and default overwrite behavior.
|
||||
</summary>
|
||||
<param name="capacity">The maximum capcity of the buffer.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.#ctor(System.Int32,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> class that is empty and has the specified initial capacity and overwrite behavior.
|
||||
</summary>
|
||||
<param name="capacity">The maximum capcity of the buffer.</param>
|
||||
<param name="allowOverwrite">If set to <c>true</c> the buffer will automatically overwrite the oldest items when full.</param>
|
||||
<exception cref="T:System.ArgumentException">Thown if the <paramref name="capacity"/> is less than zero.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Clear">
|
||||
<summary>
|
||||
Removes all items from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Contains(`0)">
|
||||
<summary>
|
||||
Determines whether the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> contains a specific value.
|
||||
</summary>
|
||||
<param name="item">The object to locate in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns><c>true</c> if <paramref name="item"/> is found in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(`0[])">
|
||||
<summary>
|
||||
Copies the entire <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(`0[],System.Int32)">
|
||||
<summary>
|
||||
Copies the entire <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(System.Int32,`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies a range of elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="index">The zero-based index in the source <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> at which copying begins.</param>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(System.Int32)">
|
||||
<summary>
|
||||
Removes and returns the specified number of objects from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to remove and return from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns>The objects that are removed from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(`0[])">
|
||||
<summary>
|
||||
Copies and removes the specified number elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies and removes the specified number elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
<returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get">
|
||||
<summary>
|
||||
Removes and returns the object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<returns>The object that is removed from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
<remarks>This method is similar to the <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek"/> method, but <c>Peek</c> does not modify the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> for the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek">
|
||||
<summary>
|
||||
Returns the object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> without removing it.
|
||||
</summary>
|
||||
<returns>The object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek(System.Int32)">
|
||||
<summary>
|
||||
Returns the specified number of objects from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to return from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns>The objects that from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.PeekLast">
|
||||
<summary>
|
||||
Returns the object at the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> without removing it.
|
||||
</summary>
|
||||
<returns>The object at the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0[])">
|
||||
<summary>
|
||||
Copies an entire compatible one-dimensional array to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the source of the elements copied to <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> plus the size of <paramref name="array"/> exceeds the capacity of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies a range of elements from a compatible one-dimensional array to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the source of the elements copied to <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> plus <paramref name="count"/> exceeds the capacity of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0)">
|
||||
<summary>
|
||||
Adds an object to the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="item">The object to add to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The value can be <c>null</c> for reference types.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> already equals the capacity and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest item in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is overwritten with <paramref name="item"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Skip(System.Int32)">
|
||||
<summary>
|
||||
Increments the starting index of the data buffer in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to increment the data buffer start index by.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.ToArray">
|
||||
<summary>
|
||||
Copies the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> elements to a new array.
|
||||
</summary>
|
||||
<returns>A new array containing elements copied from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<remarks>The <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is not modified. The order of the elements in the new array is the same as the order of the elements from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to its end.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
|
||||
<summary>
|
||||
Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Add(`0)">
|
||||
<summary>
|
||||
Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
|
||||
</summary>
|
||||
<param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Remove(`0)">
|
||||
<summary>
|
||||
Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
</summary>
|
||||
<param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
|
||||
<returns><c>true</c> if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, <c>false</c>. This method also returns <c>false</c> if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
|
||||
<exception cref="T:System.NotSupportedException">Cannot remove items from collection.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#IEnumerable{T}#GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through the collection.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#IEnumerable#GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through a collection.
|
||||
</summary>
|
||||
<returns>An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.</returns>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite">
|
||||
<summary>
|
||||
Gets or sets a value indicating whether the buffer will automatically overwrite the oldest items in the buffer when the maximum capacity is reached.
|
||||
</summary>
|
||||
<value><c>true</c> if the oldest items in the buffer are automatically overwritten when the buffer is full; otherwise, <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Capacity">
|
||||
<summary>
|
||||
Gets or sets the total number of elements the internal data structure can hold.
|
||||
</summary>
|
||||
<value>The total number of elements that the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> can contain.</value>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown if the specified new capacity is smaller than the current contents of the buffer.</exception>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Head">
|
||||
<summary>
|
||||
Gets the index of the beginning of the buffer data.
|
||||
</summary>
|
||||
<value>The index of the first element in the buffer.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.IsEmpty">
|
||||
<summary>
|
||||
Gets a value indicating whether the buffer is empty.
|
||||
</summary>
|
||||
<value><c>true</c> if buffer is empty; otherwise, <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.IsFull">
|
||||
<summary>
|
||||
Gets a value indicating whether the buffer is full.
|
||||
</summary>
|
||||
<value><c>true</c> if the buffer is full; otherwise, <c>false</c>.</value>
|
||||
<remarks>The <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.IsFull"/> property always returns <c>false</c> if the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is set to <c>true</c>.</remarks>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Size">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<value>The number of elements contained in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Tail">
|
||||
<summary>
|
||||
Gets the index of the end of the buffer data.
|
||||
</summary>
|
||||
<value>The index of the last element in the buffer.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#Count">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
</summary>
|
||||
<value>The number of elements actually contained in the <see cref="T:System.Collections.ICollection"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#IsSynchronized">
|
||||
<summary>
|
||||
Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe).
|
||||
</summary>
|
||||
<value><c>true</c> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe); otherwise, <c>false</c>. In the default implementation of <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>, this property always returns <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#SyncRoot">
|
||||
<summary>
|
||||
Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
|
||||
</summary>
|
||||
<value>An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/></value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Count">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
</summary>
|
||||
<value>The number of elements actually contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#IsReadOnly">
|
||||
<summary>
|
||||
Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
|
||||
</summary>
|
||||
<value><c>true</c> if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, <c>false</c>. In the default implementation of <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>, this property always returns <c>false</c>.</value>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
1412
FFXIVClassic Map Server/bin/Debug/Dapper.xml
Normal file
1412
FFXIVClassic Map Server/bin/Debug/Dapper.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data></configuration>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data></configuration>
|
8889
FFXIVClassic Map Server/bin/Debug/Newtonsoft.Json.xml
Normal file
8889
FFXIVClassic Map Server/bin/Debug/Newtonsoft.Json.xml
Normal file
File diff suppressed because it is too large
Load diff
11
FFXIVClassic Map Server/bin/Debug/config.ini
Normal file
11
FFXIVClassic Map Server/bin/Debug/config.ini
Normal file
|
@ -0,0 +1,11 @@
|
|||
[General]
|
||||
server_ip=141.117.161.40
|
||||
showtimestamp = true
|
||||
|
||||
[Database]
|
||||
worldid=1
|
||||
host="141.117.162.99"
|
||||
port=3306
|
||||
database="ffxiv_server"
|
||||
username="root"
|
||||
password="faqsfaqs"
|
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login10.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login10.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login2.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login2.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login5.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login5.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login6_data.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login6_data.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login7_data.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login7_data.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login8_data.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/asd/login8_data.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login1.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login1.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login11.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login11.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login2.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login2.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login22.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login22.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login3.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login3.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login4.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login4.bin
Normal file
Binary file not shown.
BIN
FFXIVClassic Map Server/bin/Debug/packets/login5.bin
Normal file
BIN
FFXIVClassic Map Server/bin/Debug/packets/login5.bin
Normal file
Binary file not shown.
78
FFXIVClassic Map Server/common/Bitfield.cs
Normal file
78
FFXIVClassic Map Server/common/Bitfield.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.common
|
||||
{
|
||||
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
sealed class BitfieldLengthAttribute : Attribute
|
||||
{
|
||||
uint length;
|
||||
|
||||
public BitfieldLengthAttribute(uint length)
|
||||
{
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public uint Length { get { return length; } }
|
||||
}
|
||||
|
||||
static class PrimitiveConversion
|
||||
{
|
||||
public static UInt32 ToUInt32<T>(T t) where T : struct
|
||||
{
|
||||
UInt32 r = 0;
|
||||
int offset = 0;
|
||||
|
||||
// For every field suitably attributed with a BitfieldLength
|
||||
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
|
||||
{
|
||||
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
|
||||
if (attrs.Length == 1)
|
||||
{
|
||||
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
|
||||
|
||||
// Calculate a bitmask of the desired length
|
||||
uint mask = 0;
|
||||
for (int i = 0; i < fieldLength; i++)
|
||||
mask |= (UInt32)1 << i;
|
||||
|
||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||
|
||||
offset += (int)fieldLength;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public static long ToLong<T>(T t) where T : struct
|
||||
{
|
||||
long r = 0;
|
||||
int offset = 0;
|
||||
|
||||
// For every field suitably attributed with a BitfieldLength
|
||||
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
|
||||
{
|
||||
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
|
||||
if (attrs.Length == 1)
|
||||
{
|
||||
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
|
||||
|
||||
// Calculate a bitmask of the desired length
|
||||
long mask = 0;
|
||||
for (int i = 0; i < fieldLength; i++)
|
||||
mask |= 1 << i;
|
||||
|
||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||
|
||||
offset += (int)fieldLength;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
74
FFXIVClassic Map Server/common/Blowfish.cs
Normal file
74
FFXIVClassic Map Server/common/Blowfish.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.common
|
||||
{
|
||||
|
||||
public class Blowfish
|
||||
{
|
||||
[DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern short initializeBlowfish(byte[] key, short keySize, uint[] P, uint[,] S);
|
||||
[DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void blowfish_encipher(ref int xl, ref int xr, uint[] P);
|
||||
[DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void blowfish_decipher(ref int xl, ref int xr, uint[] P);
|
||||
|
||||
private uint[] P = new uint[16+2];
|
||||
private uint[,] S = new uint[4,256];
|
||||
|
||||
public Blowfish(byte[] key)
|
||||
{
|
||||
InitBlowfish(key);
|
||||
}
|
||||
|
||||
private int InitBlowfish(byte[] key)
|
||||
{
|
||||
return initializeBlowfish(key, (short)key.Length, P, S);
|
||||
}
|
||||
|
||||
public void Encipher(byte[] data, int offset, int length)
|
||||
{
|
||||
if ((length - offset) % 8 != 0)
|
||||
throw new ArgumentException("Needs to be a multiple of 8");
|
||||
|
||||
for (int i = offset; i < offset+length; i+=8)
|
||||
{
|
||||
int xl = (data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24);
|
||||
int xr = (data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24);
|
||||
blowfish_encipher(ref xl, ref xr, P);
|
||||
data[i + 0] = (byte)(xl >> 0);
|
||||
data[i + 1] = (byte)(xl >> 8);
|
||||
data[i + 2] = (byte)(xl >> 16);
|
||||
data[i + 3] = (byte)(xl >> 24);
|
||||
data[i + 4] = (byte)(xr >> 0);
|
||||
data[i + 5] = (byte)(xr >> 8);
|
||||
data[i + 6] = (byte)(xr >> 16);
|
||||
data[i + 7] = (byte)(xr >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
public void Decipher(byte[] data, int offset, int length)
|
||||
{
|
||||
if ((length - offset) % 8 != 0)
|
||||
throw new ArgumentException("Needs to be a multiple of 8");
|
||||
|
||||
for (int i = offset; i < offset + length; i += 8)
|
||||
{
|
||||
int xl = (data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24);
|
||||
int xr = (data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24);
|
||||
blowfish_decipher(ref xl, ref xr, P);
|
||||
data[i + 0] = (byte)(xl >> 0);
|
||||
data[i + 1] = (byte)(xl >> 8);
|
||||
data[i + 2] = (byte)(xl >> 16);
|
||||
data[i + 3] = (byte)(xl >> 24);
|
||||
data[i + 4] = (byte)(xr >> 0);
|
||||
data[i + 5] = (byte)(xr >> 8);
|
||||
data[i + 6] = (byte)(xr >> 16);
|
||||
data[i + 7] = (byte)(xr >> 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
56
FFXIVClassic Map Server/common/Log.cs
Normal file
56
FFXIVClassic Map Server/common/Log.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.common
|
||||
{
|
||||
class Log
|
||||
{
|
||||
public static void error(String message)
|
||||
{
|
||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.Write("[ERROR] ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray ;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void debug(String message)
|
||||
{
|
||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("[DEBUG] ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void info(String message)
|
||||
{
|
||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.Write("[INFO] ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void database(String message)
|
||||
{
|
||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
Console.Write("[SQL] ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void conn(String message)
|
||||
{
|
||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.Write("[CONN] ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
}
|
541
FFXIVClassic Map Server/common/STA_INIFile.cs
Normal file
541
FFXIVClassic Map Server/common/STA_INIFile.cs
Normal file
|
@ -0,0 +1,541 @@
|
|||
// *******************************
|
||||
// *** INIFile class V2.1 ***
|
||||
// *******************************
|
||||
// *** (C)2009-2013 S.T.A. snc ***
|
||||
// *******************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace STA.Settings
|
||||
{
|
||||
|
||||
internal class INIFile
|
||||
{
|
||||
|
||||
#region "Declarations"
|
||||
|
||||
// *** Lock for thread-safe access to file and local cache ***
|
||||
private object m_Lock = new object();
|
||||
|
||||
// *** File name ***
|
||||
private string m_FileName = null;
|
||||
internal string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_FileName;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Lazy loading flag ***
|
||||
private bool m_Lazy = false;
|
||||
|
||||
// *** Automatic flushing flag ***
|
||||
private bool m_AutoFlush = false;
|
||||
|
||||
// *** Local cache ***
|
||||
private Dictionary<string, Dictionary<string, string>> m_Sections = new Dictionary<string, Dictionary<string, string>>();
|
||||
private Dictionary<string, Dictionary<string, string>> m_Modified = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
// *** Local cache modified flag ***
|
||||
private bool m_CacheModified = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Methods"
|
||||
|
||||
// *** Constructor ***
|
||||
public INIFile(string FileName)
|
||||
{
|
||||
Initialize(FileName, false, false);
|
||||
}
|
||||
|
||||
public INIFile(string FileName, bool Lazy, bool AutoFlush)
|
||||
{
|
||||
Initialize(FileName, Lazy, AutoFlush);
|
||||
}
|
||||
|
||||
// *** Initialization ***
|
||||
private void Initialize(string FileName, bool Lazy, bool AutoFlush)
|
||||
{
|
||||
m_FileName = FileName;
|
||||
m_Lazy = Lazy;
|
||||
m_AutoFlush = AutoFlush;
|
||||
if (!m_Lazy) Refresh();
|
||||
}
|
||||
|
||||
// *** Parse section name ***
|
||||
private string ParseSectionName(string Line)
|
||||
{
|
||||
if (!Line.StartsWith("[")) return null;
|
||||
if (!Line.EndsWith("]")) return null;
|
||||
if (Line.Length < 3) return null;
|
||||
return Line.Substring(1, Line.Length - 2);
|
||||
}
|
||||
|
||||
// *** Parse key+value pair ***
|
||||
private bool ParseKeyValuePair(string Line, ref string Key, ref string Value)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
int i;
|
||||
if ((i = Line.IndexOf('=')) <= 0) return false;
|
||||
|
||||
int j = Line.Length - i - 1;
|
||||
Key = Line.Substring(0, i).Trim();
|
||||
if (Key.Length <= 0) return false;
|
||||
|
||||
Value = (j > 0) ? (Line.Substring(i + 1, j).Trim()) : ("");
|
||||
return true;
|
||||
}
|
||||
|
||||
// *** Read file contents into local cache ***
|
||||
internal void Refresh()
|
||||
{
|
||||
lock (m_Lock)
|
||||
{
|
||||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
// *** Clear local cache ***
|
||||
m_Sections.Clear();
|
||||
m_Modified.Clear();
|
||||
|
||||
// *** Open the INI file ***
|
||||
try
|
||||
{
|
||||
sr = new StreamReader(m_FileName);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// *** Read up the file content ***
|
||||
Dictionary<string, string> CurrentSection = null;
|
||||
string s;
|
||||
string SectionName;
|
||||
string Key = null;
|
||||
string Value = null;
|
||||
while ((s = sr.ReadLine()) != null)
|
||||
{
|
||||
s = s.Trim();
|
||||
|
||||
// *** Check for section names ***
|
||||
SectionName = ParseSectionName(s);
|
||||
if (SectionName != null)
|
||||
{
|
||||
// *** Only first occurrence of a section is loaded ***
|
||||
if (m_Sections.ContainsKey(SectionName))
|
||||
{
|
||||
CurrentSection = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSection = new Dictionary<string, string>();
|
||||
m_Sections.Add(SectionName, CurrentSection);
|
||||
}
|
||||
}
|
||||
else if (CurrentSection != null)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
if (ParseKeyValuePair(s, ref Key, ref Value))
|
||||
{
|
||||
// *** Only first occurrence of a key is loaded ***
|
||||
if (!CurrentSection.ContainsKey(Key))
|
||||
{
|
||||
CurrentSection.Add(Key, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close file ***
|
||||
if (sr != null) sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** Flush local cache content ***
|
||||
internal void Flush()
|
||||
{
|
||||
lock (m_Lock)
|
||||
{
|
||||
PerformFlush();
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformFlush()
|
||||
{
|
||||
// *** If local cache was not modified, exit ***
|
||||
if (!m_CacheModified) return;
|
||||
m_CacheModified = false;
|
||||
|
||||
// *** Check if original file exists ***
|
||||
bool OriginalFileExists = File.Exists(m_FileName);
|
||||
|
||||
// *** Get temporary file name ***
|
||||
string TmpFileName = Path.ChangeExtension(m_FileName, "$n$");
|
||||
|
||||
// *** Copy content of original file to temporary file, replace modified values ***
|
||||
StreamWriter sw = null;
|
||||
|
||||
// *** Create the temporary file ***
|
||||
sw = new StreamWriter(TmpFileName);
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> CurrentSection = null;
|
||||
if (OriginalFileExists)
|
||||
{
|
||||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
// *** Open the original file ***
|
||||
sr = new StreamReader(m_FileName);
|
||||
|
||||
// *** Read the file original content, replace changes with local cache values ***
|
||||
string s;
|
||||
string SectionName;
|
||||
string Key = null;
|
||||
string Value = null;
|
||||
bool Unmodified;
|
||||
bool Reading = true;
|
||||
while (Reading)
|
||||
{
|
||||
s = sr.ReadLine();
|
||||
Reading = (s != null);
|
||||
|
||||
// *** Check for end of file ***
|
||||
if (Reading)
|
||||
{
|
||||
Unmodified = true;
|
||||
s = s.Trim();
|
||||
SectionName = ParseSectionName(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unmodified = false;
|
||||
SectionName = null;
|
||||
}
|
||||
|
||||
// *** Check for section names ***
|
||||
if ((SectionName != null) || (!Reading))
|
||||
{
|
||||
if (CurrentSection != null)
|
||||
{
|
||||
// *** Write all remaining modified values before leaving a section ****
|
||||
if (CurrentSection.Count > 0)
|
||||
{
|
||||
foreach (string fkey in CurrentSection.Keys)
|
||||
{
|
||||
if (CurrentSection.TryGetValue(fkey, out Value))
|
||||
{
|
||||
sw.Write(fkey);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(Value);
|
||||
}
|
||||
}
|
||||
sw.WriteLine();
|
||||
CurrentSection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (Reading)
|
||||
{
|
||||
// *** Check if current section is in local modified cache ***
|
||||
if (!m_Modified.TryGetValue(SectionName, out CurrentSection))
|
||||
{
|
||||
CurrentSection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CurrentSection != null)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
if (ParseKeyValuePair(s, ref Key, ref Value))
|
||||
{
|
||||
if (CurrentSection.TryGetValue(Key, out Value))
|
||||
{
|
||||
// *** Write modified value to temporary file ***
|
||||
Unmodified = false;
|
||||
CurrentSection.Remove(Key);
|
||||
|
||||
sw.Write(Key);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** Write unmodified lines from the original file ***
|
||||
if (Unmodified)
|
||||
{
|
||||
sw.WriteLine(s);
|
||||
}
|
||||
}
|
||||
|
||||
// *** Close the original file ***
|
||||
sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close files ***
|
||||
if (sr != null) sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Cycle on all remaining modified values ***
|
||||
foreach (KeyValuePair<string, Dictionary<string, string>> SectionPair in m_Modified)
|
||||
{
|
||||
CurrentSection = SectionPair.Value;
|
||||
if (CurrentSection.Count > 0)
|
||||
{
|
||||
sw.WriteLine();
|
||||
|
||||
// *** Write the section name ***
|
||||
sw.Write('[');
|
||||
sw.Write(SectionPair.Key);
|
||||
sw.WriteLine(']');
|
||||
|
||||
// *** Cycle on all key+value pairs in the section ***
|
||||
foreach (KeyValuePair<string, string> ValuePair in CurrentSection)
|
||||
{
|
||||
// *** Write the key+value pair ***
|
||||
sw.Write(ValuePair.Key);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(ValuePair.Value);
|
||||
}
|
||||
CurrentSection.Clear();
|
||||
}
|
||||
}
|
||||
m_Modified.Clear();
|
||||
|
||||
// *** Close the temporary file ***
|
||||
sw.Close();
|
||||
sw = null;
|
||||
|
||||
// *** Rename the temporary file ***
|
||||
File.Copy(TmpFileName, m_FileName, true);
|
||||
|
||||
// *** Delete the temporary file ***
|
||||
File.Delete(TmpFileName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close files ***
|
||||
if (sw != null) sw.Close();
|
||||
sw = null;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Read a value from local cache ***
|
||||
internal string GetValue(string SectionName, string Key, string DefaultValue)
|
||||
{
|
||||
// *** Lazy loading ***
|
||||
if (m_Lazy)
|
||||
{
|
||||
m_Lazy = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
lock (m_Lock)
|
||||
{
|
||||
// *** Check if the section exists ***
|
||||
Dictionary<string, string> Section;
|
||||
if (!m_Sections.TryGetValue(SectionName, out Section)) return DefaultValue;
|
||||
|
||||
// *** Check if the key exists ***
|
||||
string Value;
|
||||
if (!Section.TryGetValue(Key, out Value)) return DefaultValue;
|
||||
|
||||
// *** Return the found value ***
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Insert or modify a value in local cache ***
|
||||
internal void SetValue(string SectionName, string Key, string Value)
|
||||
{
|
||||
// *** Lazy loading ***
|
||||
if (m_Lazy)
|
||||
{
|
||||
m_Lazy = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
lock (m_Lock)
|
||||
{
|
||||
// *** Flag local cache modification ***
|
||||
m_CacheModified = true;
|
||||
|
||||
// *** Check if the section exists ***
|
||||
Dictionary<string, string> Section;
|
||||
if (!m_Sections.TryGetValue(SectionName, out Section))
|
||||
{
|
||||
// *** If it doesn't, add it ***
|
||||
Section = new Dictionary<string, string>();
|
||||
m_Sections.Add(SectionName,Section);
|
||||
}
|
||||
|
||||
// *** Modify the value ***
|
||||
if (Section.ContainsKey(Key)) Section.Remove(Key);
|
||||
Section.Add(Key, Value);
|
||||
|
||||
// *** Add the modified value to local modified values cache ***
|
||||
if (!m_Modified.TryGetValue(SectionName, out Section))
|
||||
{
|
||||
Section = new Dictionary<string, string>();
|
||||
m_Modified.Add(SectionName, Section);
|
||||
}
|
||||
|
||||
if (Section.ContainsKey(Key)) Section.Remove(Key);
|
||||
Section.Add(Key, Value);
|
||||
|
||||
// *** Automatic flushing : immediately write any modification to the file ***
|
||||
if (m_AutoFlush) PerformFlush();
|
||||
}
|
||||
}
|
||||
|
||||
// *** Encode byte array ***
|
||||
private string EncodeByteArray(byte[] Value)
|
||||
{
|
||||
if (Value == null) return null;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte b in Value)
|
||||
{
|
||||
string hex = Convert.ToString(b, 16);
|
||||
int l = hex.Length;
|
||||
if (l > 2)
|
||||
{
|
||||
sb.Append(hex.Substring(l - 2, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (l < 2) sb.Append("0");
|
||||
sb.Append(hex);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
// *** Decode byte array ***
|
||||
private byte[] DecodeByteArray(string Value)
|
||||
{
|
||||
if (Value == null) return null;
|
||||
|
||||
int l = Value.Length;
|
||||
if (l < 2) return new byte[] { };
|
||||
|
||||
l /= 2;
|
||||
byte[] Result = new byte[l];
|
||||
for (int i = 0; i < l; i++) Result[i] = Convert.ToByte(Value.Substring(i * 2, 2), 16);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// *** Getters for various types ***
|
||||
internal bool GetValue(string SectionName, string Key, bool DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
int Value;
|
||||
if (int.TryParse(StringValue, out Value)) return (Value != 0);
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal int GetValue(string SectionName, string Key, int DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
int Value;
|
||||
if (int.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal uint GetValue(string SectionName, string Key, uint DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
uint Value;
|
||||
if (uint.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal long GetValue(string SectionName, string Key, long DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
long Value;
|
||||
if (long.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal double GetValue(string SectionName, string Key, double DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
double Value;
|
||||
if (double.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal byte[] GetValue(string SectionName, string Key, byte[] DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, EncodeByteArray(DefaultValue));
|
||||
try
|
||||
{
|
||||
return DecodeByteArray(StringValue);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return DefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal DateTime GetValue(string SectionName, string Key, DateTime DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
DateTime Value;
|
||||
if (DateTime.TryParse(StringValue, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AssumeLocal, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
// *** Setters for various types ***
|
||||
internal void SetValue(string SectionName, string Key, bool Value)
|
||||
{
|
||||
SetValue(SectionName, Key, (Value) ? ("1") : ("0"));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, int Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, long Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, double Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, byte[] Value)
|
||||
{
|
||||
SetValue(SectionName, Key, EncodeByteArray(Value));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, DateTime Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
59
FFXIVClassic Map Server/common/Utils.cs
Normal file
59
FFXIVClassic Map Server/common/Utils.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.common
|
||||
{
|
||||
static class Utils
|
||||
{
|
||||
private static readonly uint[] _lookup32 = CreateLookup32();
|
||||
|
||||
private static uint[] CreateLookup32()
|
||||
{
|
||||
var result = new uint[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
string s = i.ToString("X2");
|
||||
result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ByteArrayToHex(byte[] bytes)
|
||||
{
|
||||
var lookup32 = _lookup32;
|
||||
var result = new char[(bytes.Length * 3) + ((bytes.Length/16) < 1 ? 1 : (bytes.Length/16)*3) + bytes.Length+60];
|
||||
int numNewLines = 0;
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
var val = lookup32[bytes[i]];
|
||||
result[(3 * i) + (17 * numNewLines) + 0] = (char)val;
|
||||
result[(3 * i) + (17 * numNewLines) + 1] = (char)(val >> 16);
|
||||
result[(3 * i) + (17 * numNewLines) + 2] = ' ';
|
||||
|
||||
result[(numNewLines * (3*16+17)) + (3 * 16) + (i % 16)] = (char)bytes[i] >= 32 && (char)bytes[i] <= 126 ? (char)bytes[i] : '.';
|
||||
|
||||
if (i != bytes.Length - 1 && bytes.Length > 16 && i != 0 && (i+1) % 16 == 0)
|
||||
{
|
||||
result[(numNewLines * (3*16+17)) + (3 * 16) + (16)] = '\n';
|
||||
numNewLines++;
|
||||
}
|
||||
|
||||
}
|
||||
return new string(result);
|
||||
}
|
||||
|
||||
public static UInt32 UnixTimeStampUTC()
|
||||
{
|
||||
UInt32 unixTimeStamp;
|
||||
DateTime currentTime = DateTime.Now;
|
||||
DateTime zuluTime = currentTime.ToUniversalTime();
|
||||
DateTime unixEpoch = new DateTime(1970, 1, 1);
|
||||
unixTimeStamp = (UInt32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
|
||||
return unixTimeStamp;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
52
FFXIVClassic Map Server/dataobjects/Actor.cs
Normal file
52
FFXIVClassic Map Server/dataobjects/Actor.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.dataobjects
|
||||
{
|
||||
class Actor
|
||||
{
|
||||
enum Appearance {
|
||||
MODEL,
|
||||
SIZE,
|
||||
COLORINFO,
|
||||
FACEINFO,
|
||||
HIGHLIGHT_HAIR,
|
||||
VOICE,
|
||||
WEAPON1,
|
||||
WEAPON2,
|
||||
WEAPON3,
|
||||
HEADGEAR,
|
||||
BODYGEAR,
|
||||
LEGSGEAR,
|
||||
HANDSGEAR,
|
||||
FEETGEAR,
|
||||
WAISTGEAR,
|
||||
UNKNOWN1,
|
||||
R_EAR,
|
||||
L_EAR,
|
||||
UNKNOWN2,
|
||||
UNKNOWN3,
|
||||
R_FINGER,
|
||||
L_FINGER
|
||||
}
|
||||
|
||||
public uint actorID;
|
||||
|
||||
public uint displayNameID;
|
||||
public string customDisplayName;
|
||||
|
||||
public uint[] appearanceIDs;
|
||||
|
||||
public float positionX, positionY, positionZ;
|
||||
public float rotation;
|
||||
public ushort moveState;
|
||||
|
||||
public Actor(uint id)
|
||||
{
|
||||
actorID = id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
314
FFXIVClassic Map Server/dataobjects/CharaInfo.cs
Normal file
314
FFXIVClassic Map Server/dataobjects/CharaInfo.cs
Normal file
|
@ -0,0 +1,314 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.dataobjects
|
||||
{
|
||||
class CharaInfo
|
||||
{
|
||||
public uint tribe = 0;
|
||||
public uint size = 0;
|
||||
public uint voice = 0;
|
||||
public ushort skinColor = 0;
|
||||
|
||||
public ushort hairStyle = 0;
|
||||
public ushort hairColor = 0;
|
||||
public ushort hairHighlightColor = 0;
|
||||
public ushort eyeColor = 0;
|
||||
public ushort characteristicsColor = 0;
|
||||
|
||||
public struct FaceInfo
|
||||
{
|
||||
[BitfieldLength(5)]
|
||||
public uint characteristics;
|
||||
[BitfieldLength(3)]
|
||||
public uint characteristicsColor;
|
||||
[BitfieldLength(6)]
|
||||
public uint type;
|
||||
[BitfieldLength(2)]
|
||||
public uint ears;
|
||||
[BitfieldLength(2)]
|
||||
public uint mouth;
|
||||
[BitfieldLength(2)]
|
||||
public uint features;
|
||||
[BitfieldLength(3)]
|
||||
public uint nose;
|
||||
[BitfieldLength(3)]
|
||||
public uint eyeShape;
|
||||
[BitfieldLength(1)]
|
||||
public uint irisSize;
|
||||
[BitfieldLength(3)]
|
||||
public uint eyebrows;
|
||||
[BitfieldLength(2)]
|
||||
public uint unknown;
|
||||
}
|
||||
|
||||
public uint faceType = 0;
|
||||
public uint faceEyebrows = 0;
|
||||
public uint faceEyeShape = 0;
|
||||
public uint faceIrisSize = 0;
|
||||
public uint faceNose = 0;
|
||||
public uint faceMouth = 0;
|
||||
public uint faceFeatures = 0;
|
||||
public uint characteristics = 0;
|
||||
public uint ears = 0;
|
||||
|
||||
public uint guardian = 0;
|
||||
public uint birthMonth = 0;
|
||||
public uint birthDay = 0;
|
||||
public uint currentClass = 0;
|
||||
public uint currentJob = 0;
|
||||
public uint allegiance = 0;
|
||||
|
||||
public uint mainHand = 0;
|
||||
public uint offHand = 0;
|
||||
|
||||
public uint headGear = 0;
|
||||
public uint bodyGear = 0;
|
||||
public uint legsGear = 0;
|
||||
public uint handsGear = 0;
|
||||
public uint feetGear = 0;
|
||||
public uint waistGear = 0;
|
||||
public uint rightEarGear = 0;
|
||||
public uint leftEarGear = 0;
|
||||
public uint rightFingerGear = 0;
|
||||
public uint leftFingerGear = 0;
|
||||
|
||||
public uint currentLevel = 1;
|
||||
|
||||
public static CharaInfo getFromNewCharRequest(String encoded)
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(encoded.Replace('-', '+').Replace('_', '/'));
|
||||
CharaInfo info = new CharaInfo();
|
||||
|
||||
using (MemoryStream stream = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryReader reader = new BinaryReader(stream))
|
||||
{
|
||||
uint version = reader.ReadUInt32();
|
||||
uint unknown1 = reader.ReadUInt32();
|
||||
info.tribe = reader.ReadByte();
|
||||
info.size = reader.ReadByte();
|
||||
info.hairStyle = reader.ReadUInt16();
|
||||
info.hairHighlightColor = reader.ReadUInt16();
|
||||
info.faceType = reader.ReadByte();
|
||||
info.characteristics = reader.ReadByte();
|
||||
info.characteristicsColor = reader.ReadByte();
|
||||
|
||||
reader.ReadUInt32();
|
||||
|
||||
info.faceEyebrows = reader.ReadByte();
|
||||
info.faceIrisSize = reader.ReadByte();
|
||||
info.faceEyeShape = reader.ReadByte();
|
||||
info.faceNose = reader.ReadByte();
|
||||
info.faceFeatures = reader.ReadByte();
|
||||
info.faceMouth = reader.ReadByte();
|
||||
info.ears = reader.ReadByte();
|
||||
info.hairColor = reader.ReadUInt16();
|
||||
|
||||
reader.ReadUInt32();
|
||||
|
||||
info.skinColor = reader.ReadUInt16();
|
||||
info.eyeColor = reader.ReadUInt16();
|
||||
|
||||
info.voice = reader.ReadByte();
|
||||
info.guardian = reader.ReadByte();
|
||||
info.birthMonth = reader.ReadByte();
|
||||
info.birthDay = reader.ReadByte();
|
||||
info.currentClass = reader.ReadUInt16();
|
||||
|
||||
reader.ReadUInt32();
|
||||
reader.ReadUInt32();
|
||||
reader.ReadUInt32();
|
||||
|
||||
reader.BaseStream.Seek(0x10, SeekOrigin.Current);
|
||||
|
||||
info.allegiance = reader.ReadByte();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public String buildForCharaList(Character chara)
|
||||
{
|
||||
byte[] data;
|
||||
|
||||
mainHand = 79707136;
|
||||
offHand = 32509954;
|
||||
headGear = 43008;
|
||||
bodyGear = 43008;
|
||||
legsGear = 43008;
|
||||
handsGear = 43008;
|
||||
feetGear = 43008;
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
||||
{
|
||||
//Build faceinfo for later
|
||||
FaceInfo faceInfo = new FaceInfo();
|
||||
faceInfo.characteristics = characteristics;
|
||||
faceInfo.characteristicsColor = characteristicsColor;
|
||||
faceInfo.type = faceType;
|
||||
faceInfo.ears = ears;
|
||||
faceInfo.features = faceFeatures;
|
||||
faceInfo.eyebrows = faceEyebrows;
|
||||
faceInfo.eyeShape = faceEyeShape;
|
||||
faceInfo.irisSize = faceIrisSize;
|
||||
faceInfo.mouth = faceMouth;
|
||||
faceInfo.nose = faceNose;
|
||||
|
||||
|
||||
string location1 = "prv0Inn01\0";
|
||||
string location2 = "defaultTerritory\0";
|
||||
|
||||
writer.Write((UInt32)0x000004c0);
|
||||
writer.Write((UInt32)0x232327ea);
|
||||
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(chara.name + '\0').Length);
|
||||
writer.Write(System.Text.Encoding.UTF8.GetBytes(chara.name + '\0'));
|
||||
writer.Write((UInt32)0x1c);
|
||||
writer.Write((UInt32)0x04);
|
||||
writer.Write((UInt32)getTribeModel());
|
||||
writer.Write((UInt32)size);
|
||||
uint colorVal = skinColor | (uint)(hairColor << 10) | (uint)(eyeColor << 20);
|
||||
writer.Write((UInt32)colorVal);
|
||||
|
||||
var bitfield = PrimitiveConversion.ToUInt32(faceInfo);
|
||||
|
||||
writer.Write((UInt32)bitfield); //FACE, Figure this out!
|
||||
uint hairVal = hairHighlightColor | (uint)(hairStyle << 10) | (uint)(characteristicsColor << 20);
|
||||
writer.Write((UInt32)hairVal);
|
||||
writer.Write((UInt32)voice);
|
||||
writer.Write((UInt32)mainHand);
|
||||
writer.Write((UInt32)offHand);
|
||||
|
||||
writer.Write((UInt32)0);
|
||||
writer.Write((UInt32)0);
|
||||
writer.Write((UInt32)0);
|
||||
writer.Write((UInt32)0);
|
||||
writer.Write((UInt32)0);
|
||||
|
||||
writer.Write((UInt32)headGear);
|
||||
writer.Write((UInt32)bodyGear);
|
||||
writer.Write((UInt32)legsGear);
|
||||
writer.Write((UInt32)handsGear);
|
||||
writer.Write((UInt32)feetGear);
|
||||
writer.Write((UInt32)waistGear);
|
||||
|
||||
writer.Write((UInt32)0);
|
||||
|
||||
writer.Write((UInt32)rightEarGear);
|
||||
writer.Write((UInt32)leftEarGear);
|
||||
|
||||
writer.Write((UInt32)0);
|
||||
writer.Write((UInt32)0);
|
||||
|
||||
writer.Write((UInt32)rightFingerGear);
|
||||
writer.Write((UInt32)leftFingerGear);
|
||||
|
||||
for (int i = 0; i < 0x8; i++)
|
||||
writer.Write((byte)0);
|
||||
|
||||
writer.Write((UInt32)1);
|
||||
writer.Write((UInt32)1);
|
||||
|
||||
writer.Write((byte)currentClass);
|
||||
writer.Write((UInt16)currentLevel);
|
||||
writer.Write((byte)currentJob);
|
||||
writer.Write((UInt16)1);
|
||||
writer.Write((byte)tribe);
|
||||
|
||||
writer.Write((UInt32)0xe22222aa);
|
||||
|
||||
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(location1).Length);
|
||||
writer.Write(System.Text.Encoding.UTF8.GetBytes(location1));
|
||||
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(location2).Length);
|
||||
writer.Write(System.Text.Encoding.UTF8.GetBytes(location2));
|
||||
|
||||
writer.Write((byte)guardian);
|
||||
writer.Write((byte)birthMonth);
|
||||
writer.Write((byte)birthDay);
|
||||
|
||||
writer.Write((UInt16)0x17);
|
||||
writer.Write((UInt32)4);
|
||||
writer.Write((UInt32)4);
|
||||
|
||||
writer.BaseStream.Seek(0x10, SeekOrigin.Current);
|
||||
|
||||
writer.Write((UInt32)allegiance);
|
||||
writer.Write((UInt32)allegiance);
|
||||
}
|
||||
|
||||
data = stream.GetBuffer();
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(data).Replace('+', '-').Replace('/', '_');
|
||||
}
|
||||
|
||||
public static String debug()
|
||||
{
|
||||
byte[] bytes = File.ReadAllBytes("./packets/charaInfo.bin");
|
||||
|
||||
Console.WriteLine(Utils.ByteArrayToHex(bytes));
|
||||
|
||||
return Convert.ToBase64String(bytes).Replace('+', '-').Replace('/', '_');
|
||||
}
|
||||
|
||||
public UInt32 getTribeModel()
|
||||
{
|
||||
switch (tribe)
|
||||
{
|
||||
//Hyur Midlander Male
|
||||
case 1:
|
||||
default:
|
||||
return 1;
|
||||
|
||||
//Hyur Midlander Female
|
||||
case 2:
|
||||
return 2;
|
||||
|
||||
//Elezen Male
|
||||
case 4:
|
||||
case 6:
|
||||
return 3;
|
||||
|
||||
//Elezen Female
|
||||
case 5:
|
||||
case 7:
|
||||
return 4;
|
||||
|
||||
//Lalafell Male
|
||||
case 8:
|
||||
case 10:
|
||||
return 5;
|
||||
|
||||
//Lalafell Female
|
||||
case 9:
|
||||
case 11:
|
||||
return 6;
|
||||
|
||||
//Miqo'te Female
|
||||
case 12:
|
||||
case 13:
|
||||
return 8;
|
||||
|
||||
//Roegadyn Male
|
||||
case 14:
|
||||
case 15:
|
||||
return 7;
|
||||
|
||||
//Hyur Highlander Male
|
||||
case 3:
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
FFXIVClassic Map Server/dataobjects/Character.cs
Normal file
40
FFXIVClassic Map Server/dataobjects/Character.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server
|
||||
{
|
||||
class Character
|
||||
{
|
||||
public uint id;
|
||||
public ushort slot;
|
||||
public ushort serverId;
|
||||
public string name;
|
||||
public ushort state;
|
||||
public string charaInfo;
|
||||
public bool isLegacy;
|
||||
public bool doRename;
|
||||
public uint currentZoneId;
|
||||
|
||||
|
||||
|
||||
public static CharaInfo EncodedToCharacter(String charaInfo)
|
||||
{
|
||||
charaInfo.Replace("+", "-");
|
||||
charaInfo.Replace("/", "_");
|
||||
byte[] data = System.Convert.FromBase64String(charaInfo);
|
||||
|
||||
Console.WriteLine("------------Base64 printout------------------");
|
||||
Console.WriteLine(Utils.ByteArrayToHex(data));
|
||||
Console.WriteLine("------------Base64 printout------------------");
|
||||
|
||||
CharaInfo chara = new CharaInfo();
|
||||
|
||||
return chara;
|
||||
}
|
||||
}
|
||||
}
|
102
FFXIVClassic Map Server/dataobjects/Player.cs
Normal file
102
FFXIVClassic Map Server/dataobjects/Player.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
using FFXIVClassic_Lobby_Server;
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.dataobjects
|
||||
{
|
||||
class Player
|
||||
{
|
||||
Actor playerActor;
|
||||
|
||||
ClientConnection conn1;
|
||||
ClientConnection conn2;
|
||||
|
||||
public uint characterID = 0;
|
||||
public uint actorID = 0;
|
||||
|
||||
uint currentZoneID = 0;
|
||||
|
||||
List<Actor> actorInstanceList = new List<Actor>();
|
||||
|
||||
bool isDisconnected;
|
||||
|
||||
public Player(uint actorId)
|
||||
{
|
||||
this.actorID = actorId;
|
||||
createPlayerActor(actorId, null);
|
||||
}
|
||||
|
||||
public void addConnection(ClientConnection conn)
|
||||
{
|
||||
if (conn1 == null && conn2 != null)
|
||||
conn1 = conn;
|
||||
else if (conn2 == null && conn1 != null)
|
||||
conn2 = conn;
|
||||
else
|
||||
conn1 = conn;
|
||||
}
|
||||
|
||||
public bool isClientConnectionsReady()
|
||||
{
|
||||
return (conn1 != null && conn2 != null);
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
isDisconnected = true;
|
||||
conn1.disconnect();
|
||||
conn2.disconnect();
|
||||
}
|
||||
|
||||
public void setConnection1(ClientConnection conn)
|
||||
{
|
||||
conn1 = conn;
|
||||
}
|
||||
|
||||
public void setConnection2(ClientConnection conn)
|
||||
{
|
||||
conn2 = conn;
|
||||
}
|
||||
|
||||
public ClientConnection getConnection1()
|
||||
{
|
||||
return conn1;
|
||||
}
|
||||
|
||||
public ClientConnection getConnection2()
|
||||
{
|
||||
return conn1;
|
||||
}
|
||||
|
||||
public void createPlayerActor(uint actorId, Character chara)
|
||||
{
|
||||
playerActor = new Actor(actorId);
|
||||
actorInstanceList.Add(playerActor);
|
||||
}
|
||||
|
||||
public void updatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
||||
{
|
||||
playerActor.positionX = x;
|
||||
playerActor.positionY = y;
|
||||
playerActor.positionZ = z;
|
||||
playerActor.rotation = rot;
|
||||
playerActor.moveState = moveState;
|
||||
}
|
||||
|
||||
public void sendMotd()
|
||||
{
|
||||
World world = Database.getServer(ConfigConstants.DATABASE_WORLDID);
|
||||
//sendChat(world.motd);
|
||||
}
|
||||
|
||||
public void sendChat(Player sender, string message, int mode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
20
FFXIVClassic Map Server/dataobjects/World.cs
Normal file
20
FFXIVClassic Map Server/dataobjects/World.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.dataobjects
|
||||
{
|
||||
class World
|
||||
{
|
||||
public ushort id;
|
||||
public string address;
|
||||
public ushort port;
|
||||
public ushort listPosition;
|
||||
public ushort population;
|
||||
public string name;
|
||||
public bool isActive;
|
||||
public string motd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.exe.config
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.csprojResolveAssemblyReference.cache
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.exe
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.pdb
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Cyotek.Collections.Generic.CircularBuffer.dll
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Dapper.dll
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\MySql.Data.dll
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Newtonsoft.Json.dll
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Cyotek.Collections.Generic.CircularBuffer.xml
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Dapper.pdb
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Dapper.xml
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Newtonsoft.Json.xml
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.exe
|
||||
c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.pdb
|
7
FFXIVClassic Map Server/packages.config
Normal file
7
FFXIVClassic Map Server/packages.config
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Cyotek.CircularBuffer" version="1.0.0.0" targetFramework="net45" />
|
||||
<package id="Dapper" version="1.42" targetFramework="net45" />
|
||||
<package id="MySql.Data" version="6.9.7" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
||||
</packages>
|
289
FFXIVClassic Map Server/packets/BasePacket.cs
Normal file
289
FFXIVClassic Map Server/packets/BasePacket.cs
Normal file
|
@ -0,0 +1,289 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.packets
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BasePacketHeader
|
||||
{
|
||||
public byte isAuthenticated;
|
||||
public byte isEncrypted;
|
||||
public ushort reserved;
|
||||
public ushort packetSize;
|
||||
public ushort numSubpackets;
|
||||
public uint unknown1; //Id?
|
||||
public uint unknown2; //Usually 0x13B
|
||||
}
|
||||
|
||||
public class BasePacket{
|
||||
public const int BASEPACKET_SIZE = 0x10;
|
||||
|
||||
public BasePacketHeader header;
|
||||
public byte[] data;
|
||||
|
||||
public unsafe BasePacket(String path)
|
||||
{
|
||||
byte[] bytes = File.ReadAllBytes(path);
|
||||
|
||||
if (bytes.Length < BASEPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Packet was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[0])
|
||||
{
|
||||
header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
||||
}
|
||||
|
||||
if (bytes.Length < header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
}
|
||||
|
||||
public unsafe BasePacket(byte[] bytes)
|
||||
{
|
||||
if (bytes.Length < BASEPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Packet was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[0])
|
||||
{
|
||||
header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
||||
}
|
||||
|
||||
if (bytes.Length < header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
}
|
||||
|
||||
public unsafe BasePacket(byte[] bytes, ref int offset)
|
||||
{
|
||||
if (bytes.Length < offset + BASEPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Packet was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[offset])
|
||||
{
|
||||
header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
||||
}
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
if (bytes.Length < offset + header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, offset + BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
|
||||
offset += packetSize;
|
||||
}
|
||||
|
||||
public BasePacket(BasePacketHeader header, byte[] data)
|
||||
{
|
||||
this.header = header;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public List<SubPacket> getSubpackets()
|
||||
{
|
||||
List<SubPacket> subpackets = new List<SubPacket>(header.numSubpackets);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
while (offset < data.Length)
|
||||
subpackets.Add(new SubPacket(data, ref offset));
|
||||
|
||||
return subpackets;
|
||||
}
|
||||
|
||||
public unsafe static BasePacketHeader getHeader(byte[] bytes)
|
||||
{
|
||||
BasePacketHeader header;
|
||||
if (bytes.Length < BASEPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Packet was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[0])
|
||||
{
|
||||
header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
public byte[] getHeaderBytes()
|
||||
{
|
||||
int size = Marshal.SizeOf(header);
|
||||
byte[] arr = new byte[size];
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(header, ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public byte[] getPacketBytes()
|
||||
{
|
||||
byte[] outBytes = new byte[header.packetSize];
|
||||
Array.Copy(getHeaderBytes(), 0, outBytes, 0, BASEPACKET_SIZE);
|
||||
Array.Copy(data, 0, outBytes, BASEPACKET_SIZE, data.Length);
|
||||
return outBytes;
|
||||
}
|
||||
|
||||
#region Utility Functions
|
||||
public static BasePacket createPacket(List<SubPacket> subpackets, bool isAuthed, bool isEncrypted)
|
||||
{
|
||||
//Create Header
|
||||
BasePacketHeader header = new BasePacketHeader();
|
||||
byte[] data = null;
|
||||
|
||||
header.isAuthenticated = isAuthed?(byte)1:(byte)0;
|
||||
header.isEncrypted = isEncrypted?(byte)1:(byte)0;
|
||||
header.numSubpackets = (ushort)subpackets.Count;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
|
||||
//Get packet size
|
||||
foreach (SubPacket subpacket in subpackets)
|
||||
header.packetSize += subpacket.header.subpacketSize;
|
||||
|
||||
data = new byte[header.packetSize-0x10];
|
||||
|
||||
//Add Subpackets
|
||||
int offset = 0;
|
||||
foreach (SubPacket subpacket in subpackets)
|
||||
{
|
||||
byte[] subpacketData = subpacket.getBytes();
|
||||
Array.Copy(subpacketData, 0, data, offset, subpacketData.Length);
|
||||
offset += (ushort)subpacketData.Length;
|
||||
}
|
||||
|
||||
Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);
|
||||
|
||||
BasePacket packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static BasePacket createPacket(SubPacket subpacket, bool isAuthed, bool isEncrypted)
|
||||
{
|
||||
//Create Header
|
||||
BasePacketHeader header = new BasePacketHeader();
|
||||
byte[] data = null;
|
||||
|
||||
header.isAuthenticated = isAuthed ? (byte)1 : (byte)0;
|
||||
header.isEncrypted = isEncrypted ? (byte)1 : (byte)0;
|
||||
header.numSubpackets = (ushort)1;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
|
||||
//Get packet size
|
||||
header.packetSize += subpacket.header.subpacketSize;
|
||||
|
||||
data = new byte[header.packetSize - 0x10];
|
||||
|
||||
//Add Subpackets
|
||||
byte[] subpacketData = subpacket.getBytes();
|
||||
Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);
|
||||
|
||||
Debug.Assert(data != null);
|
||||
|
||||
BasePacket packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static BasePacket createPacket(byte[] data, bool isAuthed, bool isEncrypted)
|
||||
{
|
||||
|
||||
Debug.Assert(data != null);
|
||||
|
||||
//Create Header
|
||||
BasePacketHeader header = new BasePacketHeader();
|
||||
|
||||
header.isAuthenticated = isAuthed ? (byte)1 : (byte)0;
|
||||
header.isEncrypted = isEncrypted ? (byte)1 : (byte)0;
|
||||
header.numSubpackets = (ushort)1;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
|
||||
//Get packet size
|
||||
header.packetSize += (ushort)data.Length;
|
||||
|
||||
BasePacket packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static unsafe void encryptPacket(Blowfish blowfish, BasePacket packet)
|
||||
{
|
||||
byte[] data = packet.data;
|
||||
int size = packet.header.packetSize;
|
||||
|
||||
int offset = 0;
|
||||
while (offset < data.Length) {
|
||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
SubPacketHeader header;
|
||||
fixed (byte* pdata = &data[offset])
|
||||
{
|
||||
header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
||||
}
|
||||
|
||||
if (data.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
blowfish.Encipher(data, offset + 0x10, header.subpacketSize-0x10);
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static unsafe void decryptPacket(Blowfish blowfish, ref BasePacket packet)
|
||||
{
|
||||
byte[] data = packet.data;
|
||||
int size = packet.header.packetSize;
|
||||
|
||||
int offset = 0;
|
||||
while (offset < data.Length)
|
||||
{
|
||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
SubPacketHeader header;
|
||||
fixed (byte* pdata = &data[offset])
|
||||
{
|
||||
header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
||||
}
|
||||
|
||||
if (data.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
blowfish.Decipher(data, offset + 0x10, header.subpacketSize-0x10);
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void debugPrintPacket()
|
||||
{
|
||||
#if DEBUG
|
||||
Console.BackgroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine("IsAuthed: {0}, IsEncrypted: {1}, Size: 0x{2:X}, Num Subpackets: {3}", header.isAuthenticated, header.isEncrypted, header.packetSize, header.numSubpackets);
|
||||
Console.WriteLine("{0}", Utils.ByteArrayToHex(getHeaderBytes()));
|
||||
foreach (SubPacket sub in getSubpackets())
|
||||
sub.debugPrintSubPacket();
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
106
FFXIVClassic Map Server/packets/SubPacket.cs
Normal file
106
FFXIVClassic Map Server/packets/SubPacket.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFXIVClassic_Lobby_Server;
|
||||
using FFXIVClassic_Lobby_Server.common;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.packets
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SubPacketHeader
|
||||
{
|
||||
public ushort subpacketSize;
|
||||
public ushort unknown0; //Always 0x03
|
||||
public uint sourceId;
|
||||
public uint targetId;
|
||||
public uint unknown1;
|
||||
public ushort unknown4; //Always 0x14
|
||||
public ushort opcode;
|
||||
public uint unknown5;
|
||||
public uint timestamp;
|
||||
public uint unknown6;
|
||||
}
|
||||
|
||||
public class SubPacket
|
||||
{
|
||||
public const int SUBPACKET_SIZE = 0x20;
|
||||
|
||||
public SubPacketHeader header;
|
||||
public byte[] data;
|
||||
|
||||
public unsafe SubPacket(byte[] bytes, ref int offset)
|
||||
{
|
||||
if (bytes.Length < offset + SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[offset])
|
||||
{
|
||||
header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
||||
}
|
||||
|
||||
if (bytes.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
data = new byte[header.subpacketSize - SUBPACKET_SIZE];
|
||||
Array.Copy(bytes, offset + SUBPACKET_SIZE, data, 0, data.Length);
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
|
||||
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data)
|
||||
{
|
||||
this.header = new SubPacketHeader();
|
||||
header.opcode = opcode;
|
||||
header.sourceId = sourceId;
|
||||
header.targetId = targetId;
|
||||
|
||||
header.timestamp = Utils.UnixTimeStampUTC();
|
||||
|
||||
header.unknown0 = 0x03;
|
||||
header.unknown1 = 0x00;
|
||||
header.unknown4 = 0x14;
|
||||
header.unknown5 = 0x00;
|
||||
header.unknown6 = 0x00;
|
||||
|
||||
this.data = data;
|
||||
|
||||
header.subpacketSize = (ushort)(0x20 + data.Length);
|
||||
}
|
||||
|
||||
public byte[] getHeaderBytes()
|
||||
{
|
||||
int size = Marshal.SizeOf(header);
|
||||
byte[] arr = new byte[size];
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(header, ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public byte[] getBytes()
|
||||
{
|
||||
byte[] outBytes = new byte[header.subpacketSize];
|
||||
Array.Copy(getHeaderBytes(), 0, outBytes, 0, SUBPACKET_SIZE);
|
||||
Array.Copy(data, 0, outBytes, SUBPACKET_SIZE, data.Length);
|
||||
return outBytes;
|
||||
}
|
||||
|
||||
public void debugPrintSubPacket()
|
||||
{
|
||||
#if DEBUG
|
||||
Console.BackgroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine("Size: 0x{0:X}, Opcode: 0x{1:X}", header.subpacketSize, header.opcode);
|
||||
Console.WriteLine("{0}", Utils.ByteArrayToHex(getHeaderBytes()));
|
||||
Console.BackgroundColor = ConsoleColor.DarkMagenta;
|
||||
Console.WriteLine("{0}", Utils.ByteArrayToHex(data));
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
33
FFXIVClassic Map Server/packets/receive/HandshakePacket.cs
Normal file
33
FFXIVClassic Map Server/packets/receive/HandshakePacket.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.receive
|
||||
{
|
||||
class HandshakePacket
|
||||
{
|
||||
bool invalidPacket = false;
|
||||
|
||||
public uint actorID;
|
||||
|
||||
public HandshakePacket(byte[] data)
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryReader binReader = new BinaryReader(mem))
|
||||
{
|
||||
try{
|
||||
binReader.BaseStream.Seek(4, SeekOrigin.Begin);
|
||||
actorID = UInt32.Parse(Encoding.ASCII.GetString(binReader.ReadBytes(10)));
|
||||
}
|
||||
catch (Exception){
|
||||
invalidPacket = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
FFXIVClassic Map Server/packets/receive/PingPacket.cs
Normal file
33
FFXIVClassic Map Server/packets/receive/PingPacket.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.receive
|
||||
{
|
||||
class PingPacket
|
||||
{
|
||||
bool invalidPacket = false;
|
||||
|
||||
public uint time;
|
||||
|
||||
public PingPacket(byte[] data)
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryReader binReader = new BinaryReader(mem))
|
||||
{
|
||||
try{
|
||||
time = binReader.ReadUInt32();
|
||||
}
|
||||
catch (Exception){
|
||||
invalidPacket = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.receive
|
||||
{
|
||||
class UpdatePlayerPositionPacket
|
||||
{
|
||||
bool invalidPacket = false;
|
||||
|
||||
public ulong time;
|
||||
public float x, y, z, rot;
|
||||
public ushort moveState; //0: Standing, 1: Walking, 2: Running
|
||||
|
||||
public UpdatePlayerPositionPacket(byte[] data)
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryReader binReader = new BinaryReader(mem))
|
||||
{
|
||||
try{
|
||||
time = binReader.ReadUInt64();
|
||||
x = binReader.ReadSingle();
|
||||
y = binReader.ReadSingle();
|
||||
z = binReader.ReadSingle();
|
||||
rot = binReader.ReadSingle();
|
||||
moveState = binReader.ReadUInt16();
|
||||
}
|
||||
catch (Exception){
|
||||
invalidPacket = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
21
FFXIVClassic Map Server/packets/send/Actor/AddActorPacket.cs
Normal file
21
FFXIVClassic Map Server/packets/send/Actor/AddActorPacket.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class AddActorPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x00CA;
|
||||
public const uint PACKET_SIZE = 0x28;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
return new SubPacket(OPCODE, playerActorID, actorID, new byte[8]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class MoveActorToPositionPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x00CF;
|
||||
public const uint PACKET_SIZE = 0x48;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
|
||||
}
|
||||
data = mem.GetBuffer();
|
||||
}
|
||||
|
||||
SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class RemoveActorPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x00CB;
|
||||
public const uint PACKET_SIZE = 0x28;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
return new SubPacket(OPCODE, playerActorID, actorID, new byte[8]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorAppearancePacket
|
||||
{
|
||||
public const ushort OPCODE = 0x00D6;
|
||||
public const uint PACKET_SIZE = 0x128;
|
||||
|
||||
public const int SIZE = 0;
|
||||
public const int COLORINFO = 1;
|
||||
public const int FACEINFO = 2;
|
||||
public const int HIGHLIGHT_HAIR = 3;
|
||||
public const int VOICE = 4;
|
||||
public const int WEAPON1 = 5;
|
||||
public const int WEAPON2 = 6;
|
||||
public const int WEAPON3 = 7;
|
||||
public const int HEADGEAR = 8;
|
||||
public const int BODYGEAR = 9;
|
||||
public const int LEGSGEAR = 10;
|
||||
public const int HANDSGEAR = 11;
|
||||
public const int FEETGEAR = 12;
|
||||
public const int WAISTGEAR = 13;
|
||||
public const int UNKNOWN1 = 14;
|
||||
public const int R_EAR = 15;
|
||||
public const int L_EAR = 16;
|
||||
public const int UNKNOWN2 = 17;
|
||||
public const int UNKNOWN3 = 18;
|
||||
public const int R_FINGER = 19;
|
||||
public const int L_FINGER = 20;
|
||||
|
||||
public uint modelID;
|
||||
public uint[] appearanceIDs;
|
||||
|
||||
public SetActorAppearancePacket(uint monsterModelID)
|
||||
{
|
||||
modelID = monsterModelID;
|
||||
appearanceIDs = new uint[22];
|
||||
}
|
||||
|
||||
public SetActorAppearancePacket(uint[] appearanceTable)
|
||||
{
|
||||
appearanceIDs = appearanceTable;
|
||||
}
|
||||
|
||||
public SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
binWriter.Write((uint)modelID);
|
||||
for (int i = 0; i < 0x1A; i++)
|
||||
{
|
||||
binWriter.Write((uint)i);
|
||||
binWriter.Write((uint)appearanceIDs[i]);
|
||||
}
|
||||
binWriter.Write((uint) 0x1B);
|
||||
binWriter.Seek(0x20, SeekOrigin.Current);
|
||||
binWriter.Write((uint) 0x1C);
|
||||
binWriter.Write((uint) 0x00);
|
||||
}
|
||||
data = mem.GetBuffer();
|
||||
}
|
||||
|
||||
SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorPositionPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x00CE;
|
||||
public const uint PACKET_SIZE = 0x48;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE-0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
|
||||
}
|
||||
data = mem.GetBuffer();
|
||||
}
|
||||
|
||||
SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
35
FFXIVClassic Map Server/packets/send/PongPacket.cs
Normal file
35
FFXIVClassic Map Server/packets/send/PongPacket.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using FFXIVClassic_Lobby_Server.common;
|
||||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.receive
|
||||
{
|
||||
class PongPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x0001;
|
||||
public const uint PACKET_SIZE = 0x40;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, ulong pingTicks)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE-0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using(BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
ulong time = pingTicks;
|
||||
binWriter.Write(time);
|
||||
}
|
||||
}
|
||||
|
||||
SubPacket subpacket = new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
return subpacket;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
33
FFXIVClassic Map Server/packets/send/SetMapPacket.cs
Normal file
33
FFXIVClassic Map Server/packets/send/SetMapPacket.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send
|
||||
{
|
||||
class SetMapPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x0005;
|
||||
public const uint PACKET_SIZE = 0x30;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint mapID)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
binWriter.Write((uint)mapID);
|
||||
binWriter.Write((uint)0x9B);
|
||||
binWriter.Write((uint)0x28);
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
}
|
||||
}
|
||||
}
|
21
FFXIVClassic Map Server/packets/send/SetMusicPacket.cs
Normal file
21
FFXIVClassic Map Server/packets/send/SetMusicPacket.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send
|
||||
{
|
||||
class SetMusicPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x000C;
|
||||
public const uint PACKET_SIZE = 0x28;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint musicID, uint musicTrackMode)
|
||||
{
|
||||
ulong combined = musicID | (musicTrackMode << 32);
|
||||
return new SubPacket(OPCODE, 0, playerActorID, BitConverter.GetBytes(combined));
|
||||
}
|
||||
}
|
||||
}
|
20
FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs
Normal file
20
FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send
|
||||
{
|
||||
class SetWeatherPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x000D;
|
||||
public const uint PACKET_SIZE = 0x28;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, long weatherID)
|
||||
{
|
||||
return new SubPacket(OPCODE, 0, playerActorID, BitConverter.GetBytes(weatherID));
|
||||
}
|
||||
}
|
||||
}
|
32
FFXIVClassic Map Server/packets/send/login/0x2Packet.cs
Normal file
32
FFXIVClassic Map Server/packets/send/login/0x2Packet.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.login
|
||||
{
|
||||
class _0x2Packet
|
||||
{
|
||||
public const ushort OPCODE = 0x0002;
|
||||
public const uint PACKET_SIZE = 0x30;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE-0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
binWriter.BaseStream.Seek(0x8, SeekOrigin.Begin);
|
||||
binWriter.Write((uint)playerActorID);
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
}
|
||||
}
|
||||
}
|
41
FFXIVClassic Map Server/packets/send/login/InitPacket.cs
Normal file
41
FFXIVClassic Map Server/packets/send/login/InitPacket.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.login
|
||||
{
|
||||
class InitPacket
|
||||
{
|
||||
public static BasePacket buildPacket(uint unknown, uint time)
|
||||
{
|
||||
byte[] data = new byte[18];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
try
|
||||
{
|
||||
binWriter.Write((short)0x18);
|
||||
binWriter.Write((short)0x7);
|
||||
binWriter.Write((uint)0);
|
||||
binWriter.Write((uint)0);
|
||||
binWriter.Write((uint)0xFFFFFD7F);
|
||||
|
||||
binWriter.Write((uint)unknown);
|
||||
binWriter.Write((uint)time);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BasePacket.createPacket(data, false, false);
|
||||
}
|
||||
}
|
||||
}
|
BIN
packages/Cyotek.CircularBuffer.1.0.0.0/Cyotek.CircularBuffer.1.0.0.0.nupkg
vendored
Normal file
BIN
packages/Cyotek.CircularBuffer.1.0.0.0/Cyotek.CircularBuffer.1.0.0.0.nupkg
vendored
Normal file
Binary file not shown.
274
packages/Cyotek.CircularBuffer.1.0.0.0/lib/net20/Cyotek.Collections.Generic.CircularBuffer.XML
vendored
Normal file
274
packages/Cyotek.CircularBuffer.1.0.0.0/lib/net20/Cyotek.Collections.Generic.CircularBuffer.XML
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Cyotek.Collections.Generic.CircularBuffer</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:Cyotek.Collections.Generic.CircularBuffer`1">
|
||||
<summary>
|
||||
Represents a first-in, first-out collection of objects using a fixed buffer and automatic overwrite support.
|
||||
</summary>
|
||||
<typeparam name="T">Specifies the type of elements in the buffer.</typeparam>
|
||||
<remarks>
|
||||
<para>The capacity of a <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is the number of elements the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> can
|
||||
hold. If an attempt is made to put more items in the buffer than available capacity, items at the start of the buffer are
|
||||
automatically overwritten. This behavior can be modified via the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property.</para>
|
||||
<para>CircularBuffer{T} accepts <c>null</c> as a valid value for reference types and allows duplicate elements.</para>
|
||||
<para>The <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Get"/> methods will remove the items that are returned from the CircularBuffer{T}. To view the contents of the CircularBuffer{T} without removing items, use the <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek"/> or <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.PeekLast"/> methods.</para>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.#ctor(System.Int32)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> class that is empty and has the specified initial capacity and default overwrite behavior.
|
||||
</summary>
|
||||
<param name="capacity">The maximum capcity of the buffer.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.#ctor(System.Int32,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> class that is empty and has the specified initial capacity and overwrite behavior.
|
||||
</summary>
|
||||
<param name="capacity">The maximum capcity of the buffer.</param>
|
||||
<param name="allowOverwrite">If set to <c>true</c> the buffer will automatically overwrite the oldest items when full.</param>
|
||||
<exception cref="T:System.ArgumentException">Thown if the <paramref name="capacity"/> is less than zero.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Clear">
|
||||
<summary>
|
||||
Removes all items from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Contains(`0)">
|
||||
<summary>
|
||||
Determines whether the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> contains a specific value.
|
||||
</summary>
|
||||
<param name="item">The object to locate in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns><c>true</c> if <paramref name="item"/> is found in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(`0[])">
|
||||
<summary>
|
||||
Copies the entire <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(`0[],System.Int32)">
|
||||
<summary>
|
||||
Copies the entire <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.CopyTo(System.Int32,`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies a range of elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="index">The zero-based index in the source <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> at which copying begins.</param>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(System.Int32)">
|
||||
<summary>
|
||||
Removes and returns the specified number of objects from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to remove and return from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns>The objects that are removed from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(`0[])">
|
||||
<summary>
|
||||
Copies and removes the specified number elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get(`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies and removes the specified number elements from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
<returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Get">
|
||||
<summary>
|
||||
Removes and returns the object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<returns>The object that is removed from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
<remarks>This method is similar to the <see cref="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek"/> method, but <c>Peek</c> does not modify the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> for the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek">
|
||||
<summary>
|
||||
Returns the object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> without removing it.
|
||||
</summary>
|
||||
<returns>The object at the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Peek(System.Int32)">
|
||||
<summary>
|
||||
Returns the specified number of objects from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to return from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</param>
|
||||
<returns>The objects that from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.PeekLast">
|
||||
<summary>
|
||||
Returns the object at the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> without removing it.
|
||||
</summary>
|
||||
<returns>The object at the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0[])">
|
||||
<summary>
|
||||
Copies an entire compatible one-dimensional array to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the source of the elements copied to <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> plus the size of <paramref name="array"/> exceeds the capacity of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0[],System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Copies a range of elements from a compatible one-dimensional array to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the source of the elements copied to <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<param name="count">The number of elements to copy.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> plus <paramref name="count"/> exceeds the capacity of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Put(`0)">
|
||||
<summary>
|
||||
Adds an object to the end of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="item">The object to add to the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>. The value can be <c>null</c> for reference types.</param>
|
||||
<exception cref="T:System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||
<remarks>If <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.Size"/> already equals the capacity and the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is <c>true</c>, the oldest item in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is overwritten with <paramref name="item"/>.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.Skip(System.Int32)">
|
||||
<summary>
|
||||
Increments the starting index of the data buffer in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<param name="count">The number of elements to increment the data buffer start index by.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.ToArray">
|
||||
<summary>
|
||||
Copies the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> elements to a new array.
|
||||
</summary>
|
||||
<returns>A new array containing elements copied from the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</returns>
|
||||
<remarks>The <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> is not modified. The order of the elements in the new array is the same as the order of the elements from the beginning of the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> to its end.</remarks>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
|
||||
<summary>
|
||||
Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Add(`0)">
|
||||
<summary>
|
||||
Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
|
||||
</summary>
|
||||
<param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Remove(`0)">
|
||||
<summary>
|
||||
Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
</summary>
|
||||
<param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
|
||||
<returns><c>true</c> if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, <c>false</c>. This method also returns <c>false</c> if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
|
||||
<exception cref="T:System.NotSupportedException">Cannot remove items from collection.</exception>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#IEnumerable{T}#GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through the collection.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
|
||||
</member>
|
||||
<member name="M:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#IEnumerable#GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through a collection.
|
||||
</summary>
|
||||
<returns>An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.</returns>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite">
|
||||
<summary>
|
||||
Gets or sets a value indicating whether the buffer will automatically overwrite the oldest items in the buffer when the maximum capacity is reached.
|
||||
</summary>
|
||||
<value><c>true</c> if the oldest items in the buffer are automatically overwritten when the buffer is full; otherwise, <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Capacity">
|
||||
<summary>
|
||||
Gets or sets the total number of elements the internal data structure can hold.
|
||||
</summary>
|
||||
<value>The total number of elements that the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/> can contain.</value>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">Thrown if the specified new capacity is smaller than the current contents of the buffer.</exception>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Head">
|
||||
<summary>
|
||||
Gets the index of the beginning of the buffer data.
|
||||
</summary>
|
||||
<value>The index of the first element in the buffer.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.IsEmpty">
|
||||
<summary>
|
||||
Gets a value indicating whether the buffer is empty.
|
||||
</summary>
|
||||
<value><c>true</c> if buffer is empty; otherwise, <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.IsFull">
|
||||
<summary>
|
||||
Gets a value indicating whether the buffer is full.
|
||||
</summary>
|
||||
<value><c>true</c> if the buffer is full; otherwise, <c>false</c>.</value>
|
||||
<remarks>The <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.IsFull"/> property always returns <c>false</c> if the <see cref="P:Cyotek.Collections.Generic.CircularBuffer`1.AllowOverwrite"/> property is set to <c>true</c>.</remarks>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Size">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.
|
||||
</summary>
|
||||
<value>The number of elements contained in the <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.Tail">
|
||||
<summary>
|
||||
Gets the index of the end of the buffer data.
|
||||
</summary>
|
||||
<value>The index of the last element in the buffer.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#Count">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
</summary>
|
||||
<value>The number of elements actually contained in the <see cref="T:System.Collections.ICollection"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#IsSynchronized">
|
||||
<summary>
|
||||
Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe).
|
||||
</summary>
|
||||
<value><c>true</c> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe); otherwise, <c>false</c>. In the default implementation of <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>, this property always returns <c>false</c>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#ICollection#SyncRoot">
|
||||
<summary>
|
||||
Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
|
||||
</summary>
|
||||
<value>An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/></value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#Count">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
</summary>
|
||||
<value>The number of elements actually contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</value>
|
||||
</member>
|
||||
<member name="P:Cyotek.Collections.Generic.CircularBuffer`1.System#Collections#Generic#ICollection{T}#IsReadOnly">
|
||||
<summary>
|
||||
Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
|
||||
</summary>
|
||||
<value><c>true</c> if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, <c>false</c>. In the default implementation of <see cref="T:Cyotek.Collections.Generic.CircularBuffer`1"/>, this property always returns <c>false</c>.</value>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
BIN
packages/Dapper.1.42/Dapper.1.42.nupkg
vendored
Normal file
BIN
packages/Dapper.1.42/Dapper.1.42.nupkg
vendored
Normal file
Binary file not shown.
1149
packages/Dapper.1.42/lib/net35/Dapper.xml
vendored
Normal file
1149
packages/Dapper.1.42/lib/net35/Dapper.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
1138
packages/Dapper.1.42/lib/net40/Dapper.xml
vendored
Normal file
1138
packages/Dapper.1.42/lib/net40/Dapper.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
1412
packages/Dapper.1.42/lib/net45/Dapper.xml
vendored
Normal file
1412
packages/Dapper.1.42/lib/net45/Dapper.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
64
packages/MySql.Data.6.9.7/CHANGES
vendored
Normal file
64
packages/MySql.Data.6.9.7/CHANGES
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
6.9.7
|
||||
- Changed default SSL mode to Preferred in connection string. Now the server connections will be using SSL if server allows it by default but it's possible to override this configuration.
|
||||
- Changed handshake process to use bytes instead of encoded strings.
|
||||
- Fix for Fabric connections (Oracle Bug #20983968).
|
||||
- Fix for Fabric plugin: fabric server selection is broken when master is faulty (Oracle Bug #21203824).
|
||||
|
||||
|
||||
6.9.6
|
||||
- Fix for Incorrect query result with Entity Framework 6 (MySql bug #74918, Oracle bug #20129927).
|
||||
- Fix for GetTimeZoneOffset to use date and time to calculate timediff (MySQL Bug #74905, Oracle Bug #20065691).
|
||||
- Fix for MySqlSimpleMembershipProvider keeps database connections open on some operations (MySQL Bug #74662, Oracle Bug #20109419)
|
||||
- Fix for Any Call to RoleExists() returns true whether or not the role exists (MySql bug #75397, Oracle bug #20325391).
|
||||
- Fix for all dateTimes set as UTC Kind (MySQL Bug #74134, Oracle Bug #20200662).
|
||||
- Fix for Invalid SQL query when eager loading two nested collections (MySQL Bug #70941, Oracle bug #18049862).
|
||||
- Fix for chinese characters used in the connection string when connecting to MySql Server (MySQL Bug #70041, Oracle Bug #18141356).
|
||||
|
||||
|
||||
|
||||
6.9.5
|
||||
- Disabled installation on-demand in Installer (Oracle Bug #19670596).
|
||||
- Fix for Generated SQL requests column that doesn't exist in LINQ to Entities (MySql bug #72004, Oracle bug #19681348).
|
||||
- Fix for MySQL Connector/NET generates incorrect SQL for LINQ 'StartsWith' queries (MySql bug #72058, Oracle bug #19680236).
|
||||
- Fix for Exception when using IEnumerable.Contains(model.property) in Where predicate (MySql bug #73643, Oracle bug #19690370).
|
||||
- Fix for Generated Sql does not contain ORDER BY statement whose is requested by LINQ (MySql bug #73549, Oracle bug #19698010).
|
||||
- Fix for Web providers registration in machine.config (removed v20 suffix) (MySQL Bug #74080, Oracle Bug #19715398)
|
||||
- Fix for Error of "Every derived table must have an alias" in LINQ to Entities when using EF6 + DbFirst + View + Take
|
||||
(MySql Bug #72148, Oracle bug #19356006).
|
||||
- Fix for 'the method or operation is not implemented' when using linq with orderby (MySQL Bug #70722, Oracle Bug #19681723).
|
||||
- Fix for Exception "The given key was not present in the dictionary" when using utf16le charset in a query. (MySql #72737, Oracle Bug #19355906)
|
||||
- Fix for Memory leak in a loop opening a connection to the database and executing a command (MySql Bug #73122, Oracle Bug #19467233).
|
||||
- Fix for Multiple issues caused by trailing and leading white space character in params using MySql Membership Provider (MySql Bug #73411, Oracle Bug #19453313)
|
||||
- Fix for bad assumption leads to modify query adding CALL statement to the beginning of the sql query even when CommandType.Text is specified (MySql Bug #72736, Oracle Bug #19325120).
|
||||
|
||||
|
||||
6.9.4
|
||||
- Added a new plugin for MySql Fabric 1.5 support
|
||||
|
||||
|
||||
6.9.3
|
||||
- Fix for Web Parts Personalization provider
|
||||
- Fix for changing the PK between two int columns (MySql Bug #71418, Oracle bug #18923294).
|
||||
- Fix for Error when Calling MySqlConnection.GetSchema("PROCEDURES WITH PARAMETERS", ...) (Oracle bug #19285959).
|
||||
- Fix for EF provider reports ManifestProviderToken = 5.6 for server 5.7 (Oracle bug #19453814).
|
||||
- Fix for Fluent API DbModelBuilder.HasColumnType is ignored in EF6 (Oracle bug #19456229).
|
||||
- Fix for Setting a PK GUID identity in Code First in EF6 no longer works in Server 5.7 (Oracle bug #19456452).
|
||||
- Non PKs declared as Identity GUID have no GUID autogenerated (Oracle bug #19456415).
|
||||
|
||||
|
||||
6.9.2
|
||||
- Add async/await compatible methods
|
||||
- Fix for Unable to read geometry column when it has been set with a SRID value. (MySql Bug #71869, Oracle Bug #19137999)
|
||||
- Fix for Exception adding a new column to an existing model as identity and PK fails when applying the migration (MySql Bug #71418, Oracle bug #18923294).
|
||||
- Added SiteMap and Personalization configuration web providers to MySql.Web Nuget Package.
|
||||
|
||||
|
||||
6.9.1
|
||||
- Fix for Exception of "duplicate entry" in MySqlSessionProvider (MySql Bug #70409, Oracle bug #18657550).
|
||||
|
||||
|
||||
6.9.0
|
||||
- Added implementation of MySQLPersonalizationProvider.
|
||||
- Added SiteMap Web provider.
|
||||
- Added Simple Membership Web Provider.
|
||||
- Fix for open sockets connections left when connection open fails, the error happens when the client try to get a connection when the max number of connections is reached in the server. (MySql #72025, Oracle Bug #18665388).
|
BIN
packages/MySql.Data.6.9.7/MySql.Data.6.9.7.nupkg
vendored
Normal file
BIN
packages/MySql.Data.6.9.7/MySql.Data.6.9.7.nupkg
vendored
Normal file
Binary file not shown.
15
packages/MySql.Data.6.9.7/Readme.txt
vendored
Normal file
15
packages/MySql.Data.6.9.7/Readme.txt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
Connector/Net 6.9 Release Notes
|
||||
------------------------------------
|
||||
|
||||
Welcome to the release notes for Connector/Net 6.9
|
||||
|
||||
What's new in 6.9
|
||||
--------------------
|
||||
|
||||
- Simple Membership Web Provider
|
||||
- Site Map Web Provider
|
||||
- Personalization Web Provider
|
||||
- MySql Fabric support
|
||||
|
||||
|
||||
Be sure and check the documentation for more information on these new features.
|
9
packages/MySql.Data.6.9.7/content/app.config.transform
vendored
Normal file
9
packages/MySql.Data.6.9.7/content/app.config.transform
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
</configuration>
|
9
packages/MySql.Data.6.9.7/content/web.config.transform
vendored
Normal file
9
packages/MySql.Data.6.9.7/content/web.config.transform
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
</configuration>
|
BIN
packages/Newtonsoft.Json.7.0.1/Newtonsoft.Json.7.0.1.nupkg
vendored
Normal file
BIN
packages/Newtonsoft.Json.7.0.1/Newtonsoft.Json.7.0.1.nupkg
vendored
Normal file
Binary file not shown.
9439
packages/Newtonsoft.Json.7.0.1/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
9439
packages/Newtonsoft.Json.7.0.1/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8582
packages/Newtonsoft.Json.7.0.1/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
8582
packages/Newtonsoft.Json.7.0.1/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8889
packages/Newtonsoft.Json.7.0.1/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
8889
packages/Newtonsoft.Json.7.0.1/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8889
packages/Newtonsoft.Json.7.0.1/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
8889
packages/Newtonsoft.Json.7.0.1/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8067
packages/Newtonsoft.Json.7.0.1/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.xml
vendored
Normal file
8067
packages/Newtonsoft.Json.7.0.1/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8414
packages/Newtonsoft.Json.7.0.1/lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.xml
vendored
Normal file
8414
packages/Newtonsoft.Json.7.0.1/lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
112
packages/Newtonsoft.Json.7.0.1/tools/install.ps1
vendored
Normal file
112
packages/Newtonsoft.Json.7.0.1/tools/install.ps1
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
# open json.net splash page on package install
|
||||
# don't open if json.net is installed as a dependency
|
||||
|
||||
try
|
||||
{
|
||||
$url = "http://www.newtonsoft.com/json/install?version=" + $package.Version
|
||||
$dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
|
||||
|
||||
if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
|
||||
{
|
||||
# user is installing from VS NuGet console
|
||||
# get reference to the window, the console host and the input history
|
||||
# show webpage if "install-package newtonsoft.json" was last input
|
||||
|
||||
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
|
||||
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
|
||||
if ($prop -eq $null) { return }
|
||||
|
||||
$hostInfo = $prop.GetValue($consoleWindow)
|
||||
if ($hostInfo -eq $null) { return }
|
||||
|
||||
$history = $hostInfo.WpfConsole.InputHistory.History
|
||||
|
||||
$lastCommand = $history | select -last 1
|
||||
|
||||
if ($lastCommand)
|
||||
{
|
||||
$lastCommand = $lastCommand.Trim().ToLower()
|
||||
if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json"))
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# user is installing from VS NuGet dialog
|
||||
# get reference to the window, then smart output console provider
|
||||
# show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation
|
||||
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
|
||||
|
||||
$instance = $instanceField.GetValue($null)
|
||||
|
||||
if ($instance -eq $null) { return }
|
||||
|
||||
$consoleProvider = $consoleField.GetValue($instance)
|
||||
if ($consoleProvider -eq $null) { return }
|
||||
|
||||
$console = $consoleProvider.CreateOutputConsole($false)
|
||||
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($messagesField -eq $null) { return }
|
||||
|
||||
$messages = $messagesField.GetValue($console)
|
||||
if ($messages -eq $null) { return }
|
||||
|
||||
$operations = $messages -split "=============================="
|
||||
|
||||
$lastOperation = $operations | select -last 1
|
||||
|
||||
if ($lastOperation)
|
||||
{
|
||||
$lastOperation = $lastOperation.ToLower()
|
||||
|
||||
$lines = $lastOperation -split "`r`n"
|
||||
|
||||
$installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1
|
||||
|
||||
if ($installMatch)
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
$pmPane = $dte2.ToolWindows.OutputWindow.OutputWindowPanes.Item("Package Manager")
|
||||
|
||||
$selection = $pmPane.TextDocument.Selection
|
||||
$selection.StartOfDocument($false)
|
||||
$selection.EndOfDocument($true)
|
||||
|
||||
if ($selection.Text.StartsWith("Attempting to gather dependencies information for package 'Newtonsoft.Json." + $package.Version + "'"))
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
# stop potential errors from bubbling up
|
||||
# worst case the splash page won't open
|
||||
}
|
||||
}
|
||||
|
||||
# still yolo
|
4
packages/repositories.config
Normal file
4
packages/repositories.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<repositories>
|
||||
<repository path="..\FFXIVClassic Map Server\packages.config" />
|
||||
</repositories>
|
Loading…
Add table
Reference in a new issue