Refactoring of BNetServer

This commit is contained in:
hondacrx
2020-07-12 00:06:43 -04:00
parent 4164384b72
commit 581d077acd
318 changed files with 2046 additions and 4694 deletions
+2 -2
View File
@@ -142,7 +142,7 @@ namespace Framework.Constants
/// </summary>
public const uint CalendarMaxInvites = 100;
public const uint CalendarDefaultResponseTime = 946684800; // 01/01/2000 00:00:00
public const LocaleConstant DefaultLocale = LocaleConstant.enUS;
public const Locale DefaultLocale = Locale.enUS;
public const int MaxAccountTutorialValues = 8;
public const int MinAuctionTime = (12 * Time.Hour);
public const int MaxConditionTargets = 3;
@@ -372,7 +372,7 @@ namespace Framework.Constants
}
}
public enum LocaleConstant
public enum Locale
{
enUS = 0,
koKR = 1,
@@ -25,11 +25,11 @@ namespace Framework.Database
const string BnetGameAccountInfo = "a.id, a.username, ab.unbandate, ab.unbandate = ab.bandate, aa.gmlevel";
PrepareStatement(LoginStatements.SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name");
PrepareStatement(LoginStatements.DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.SEL_IP_INFO, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?");
PrepareStatement(LoginStatements.DelExpiredIpBans, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.UpdExpiredAccountBans, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.SelIpInfo, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?");
PrepareStatement(LoginStatements.INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Cypher Auth', 'Failed login autoban')");
PrepareStatement(LoginStatements.InsIpAutoBanned, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Cypher Auth', 'Failed login autoban')");
PrepareStatement(LoginStatements.SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate");
PrepareStatement(LoginStatements.SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate");
PrepareStatement(LoginStatements.SEL_ACCOUNT_BANNED_ALL, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
@@ -113,16 +113,16 @@ namespace Framework.Database
PrepareStatement(LoginStatements.SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC");
PrepareStatement(LoginStatements.DEL_ACCOUNT_MUTED, "DELETE FROM account_muted WHERE guid = ?");
PrepareStatement(LoginStatements.SEL_BNET_AUTHENTICATION, "SELECT ba.id, ba.sha_pass_hash, ba.failed_logins, ba.LoginTicket, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id WHERE email = ?");
PrepareStatement(LoginStatements.UPD_BNET_AUTHENTICATION, "UPDATE battlenet_accounts SET LoginTicket = ?, LoginTicketExpiry = ? WHERE id = ?");
PrepareStatement(LoginStatements.SEL_BNET_ACCOUNT_INFO, "SELECT " + BnetAccountInfo + ", " + BnetGameAccountInfo +
PrepareStatement(LoginStatements.SelBnetAuthentication, "SELECT ba.id, ba.sha_pass_hash, ba.failed_logins, ba.LoginTicket, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id WHERE email = ?");
PrepareStatement(LoginStatements.UpdBnetAuthentication, "UPDATE battlenet_accounts SET LoginTicket = ?, LoginTicketExpiry = ? WHERE id = ?");
PrepareStatement(LoginStatements.SelBnetAccountInfo, "SELECT " + BnetAccountInfo + ", " + BnetGameAccountInfo +
" FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account" +
" LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.LoginTicket = ? ORDER BY a.id");
PrepareStatement(LoginStatements.UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?");
PrepareStatement(LoginStatements.UpdBnetLastLoginInfo, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?");
PrepareStatement(LoginStatements.UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?");
PrepareStatement(LoginStatements.SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?");
PrepareStatement(LoginStatements.SelBnetCharacterCountsByAccountId, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?");
PrepareStatement(LoginStatements.SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id LEFT JOIN account a ON rc.acctid = a.id WHERE a.battlenet_account = ?");
PrepareStatement(LoginStatements.SEL_BNET_LAST_PLAYER_CHARACTERS, "SELECT lpc.accountId, lpc.region, lpc.battlegroup, lpc.realmId, lpc.characterName, lpc.characterGUID, lpc.lastPlayedTime FROM account_last_played_character lpc LEFT JOIN account a ON lpc.accountId = a.id WHERE a.battlenet_account = ?");
PrepareStatement(LoginStatements.SelBnetLastPlayerCharacters, "SELECT lpc.accountId, lpc.region, lpc.battlegroup, lpc.realmId, lpc.characterName, lpc.characterGUID, lpc.lastPlayedTime FROM account_last_played_character lpc LEFT JOIN account a ON lpc.accountId = a.id WHERE a.battlenet_account = ?");
PrepareStatement(LoginStatements.DEL_BNET_LAST_PLAYER_CHARACTERS, "DELETE FROM account_last_played_character WHERE accountId = ? AND region = ? AND battlegroup = ?");
PrepareStatement(LoginStatements.INS_BNET_LAST_PLAYER_CHARACTERS, "INSERT INTO account_last_played_character (accountId, region, battlegroup, realmId, characterName, characterGUID, lastPlayedTime) VALUES (?,?,?,?,?,?,?)");
PrepareStatement(LoginStatements.INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)");
@@ -137,10 +137,10 @@ namespace Framework.Database
PrepareStatement(LoginStatements.SEL_BNET_MAX_ACCOUNT_INDEX, "SELECT MAX(battlenet_index) FROM account WHERE battlenet_account = ?");
PrepareStatement(LoginStatements.SEL_BNET_GAME_ACCOUNT_LIST, "SELECT a.id, a.username FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id WHERE ba.email = ?");
PrepareStatement(LoginStatements.UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE id = ?");
PrepareStatement(LoginStatements.INS_BNET_ACCOUNT_AUTO_BANNED, "INSERT INTO battlenet_account_bans(id, bandate, unbandate, bannedby, banreason) VALUES(?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')");
PrepareStatement(LoginStatements.DEL_BNET_EXPIRED_ACCOUNT_BANNED, "DELETE FROM battlenet_account_bans WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.UPD_BNET_RESET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = 0 WHERE id = ?");
PrepareStatement(LoginStatements.UpdBnetFailedLogins, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE id = ?");
PrepareStatement(LoginStatements.InsBnetAccountAutoBanned, "INSERT INTO battlenet_account_bans(id, bandate, unbandate, bannedby, banreason) VALUES(?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')");
PrepareStatement(LoginStatements.DelBnetExpiredAccountBanned, "DELETE FROM battlenet_account_bans WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.UpdBnetResetFailedLogins, "UPDATE battlenet_accounts SET failed_logins = 0 WHERE id = ?");
PrepareStatement(LoginStatements.SEL_LAST_CHAR_UNDELETE, "SELECT LastCharacterUndelete FROM battlenet_accounts WHERE Id = ?");
PrepareStatement(LoginStatements.UPD_LAST_CHAR_UNDELETE, "UPDATE battlenet_accounts SET LastCharacterUndelete = UNIX_TIMESTAMP() WHERE Id = ?");
@@ -178,10 +178,10 @@ namespace Framework.Database
public enum LoginStatements
{
SEL_REALMLIST,
DEL_EXPIRED_IP_BANS,
UPD_EXPIRED_ACCOUNT_BANS,
SEL_IP_INFO,
INS_IP_AUTO_BANNED,
DelExpiredIpBans,
UpdExpiredAccountBans,
SelIpInfo,
InsIpAutoBanned,
SEL_ACCOUNT_BANNED_ALL,
SEL_ACCOUNT_BANNED_BY_USERNAME,
DEL_ACCOUNT_BANNED,
@@ -260,14 +260,14 @@ namespace Framework.Database
SEL_ACCOUNT_MUTE_INFO,
DEL_ACCOUNT_MUTED,
SEL_BNET_AUTHENTICATION,
UPD_BNET_AUTHENTICATION,
SEL_BNET_ACCOUNT_INFO,
UPD_BNET_LAST_LOGIN_INFO,
SelBnetAuthentication,
UpdBnetAuthentication,
SelBnetAccountInfo,
UpdBnetLastLoginInfo,
UPD_BNET_GAME_ACCOUNT_LOGIN_INFO,
SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID,
SelBnetCharacterCountsByAccountId,
SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID,
SEL_BNET_LAST_PLAYER_CHARACTERS,
SelBnetLastPlayerCharacters,
DEL_BNET_LAST_PLAYER_CHARACTERS,
INS_BNET_LAST_PLAYER_CHARACTERS,
INS_BNET_ACCOUNT,
@@ -283,10 +283,10 @@ namespace Framework.Database
SEL_BNET_MAX_ACCOUNT_INDEX,
SEL_BNET_GAME_ACCOUNT_LIST,
UPD_BNET_FAILED_LOGINS,
INS_BNET_ACCOUNT_AUTO_BANNED,
DEL_BNET_EXPIRED_ACCOUNT_BANNED,
UPD_BNET_RESET_FAILED_LOGINS,
UpdBnetFailedLogins,
InsBnetAccountAutoBanned,
DelBnetExpiredAccountBanned,
UpdBnetResetFailedLogins,
SEL_LAST_CHAR_UNDELETE,
UPD_LAST_CHAR_UNDELETE,
+9
View File
@@ -50,6 +50,15 @@ namespace Framework.Database
return (T)value;
}
public T[] ReadValues<T>(int startIndex, int numColumns)
{
T[] values = new T[numColumns];
for (var c = 0; c < numColumns; ++c)
values[c] = Read<T>(startIndex + c);
return values;
}
public bool IsNull(int column)
{
return _reader.IsDBNull(column);
+4 -4
View File
@@ -25,12 +25,15 @@ namespace Framework.Networking
public class AsyncAcceptor
{
TcpListener _listener;
volatile bool _closed;
public bool Start(string ip, int port)
{
IPAddress bindIP;
if (!IPAddress.TryParse(ip, out bindIP))
{
Log.outError(LogFilter.Network, "Server can't be started: Invalid IP-Address ({0})", ip);
Log.outError(LogFilter.Network, $"Server can't be started: Invalid IP-Address: {ip}");
return false;
}
@@ -73,8 +76,5 @@ namespace Framework.Networking
_closed = true;
_listener.Stop();
}
TcpListener _listener;
volatile bool _closed;
}
}
+9 -8
View File
@@ -22,6 +22,14 @@ namespace Framework.Networking
{
public class NetworkThread<TSocketType> where TSocketType : ISocket
{
int _connections;
volatile bool _stopped;
Thread _thread;
List<TSocketType> _Sockets = new List<TSocketType>();
List<TSocketType> _newSockets = new List<TSocketType>();
public void Stop()
{
_stopped = true;
@@ -56,6 +64,7 @@ namespace Framework.Networking
}
protected virtual void SocketAdded(TSocketType sock) { }
protected virtual void SocketRemoved(TSocketType sock) { }
void AddNewSockets()
@@ -114,13 +123,5 @@ namespace Framework.Networking
_newSockets.Clear();
_Sockets.Clear();
}
int _connections;
volatile bool _stopped;
Thread _thread;
List<TSocketType> _Sockets = new List<TSocketType>();
List<TSocketType> _newSockets = new List<TSocketType>();
}
}
+37 -58
View File
@@ -20,46 +20,56 @@ using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace Framework.Networking
{
public abstract class SSLSocket : ISocket
public abstract class SSLSocket : ISocket, IDisposable
{
Socket _socket;
internal SslStream _stream;
IPEndPoint _remoteEndPoint;
byte[] _receiveBuffer;
protected SSLSocket(Socket socket)
{
_socket = socket;
_remoteAddress = ((IPEndPoint)_socket.RemoteEndPoint).Address;
_remotePort = (ushort)((IPEndPoint)_socket.RemoteEndPoint).Port;
_remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
_receiveBuffer = new byte[ushort.MaxValue];
_stream = new SslStream(new NetworkStream(socket), false);
}
public abstract void Start();
public virtual void Dispose()
{
_receiveBuffer = null;
_stream.Dispose();
}
public abstract void Accept();
public virtual bool Update()
{
return IsOpen();
return _socket.Connected;
}
public IPAddress GetRemoteIpAddress()
public IPEndPoint GetRemoteIpEndPoint()
{
return _remoteAddress;
return _remoteEndPoint;
}
public ushort GetRemotePort()
{
return _remotePort;
}
public void AsyncRead()
public async Task AsyncRead()
{
if (!IsOpen())
return;
try
{
_stream.BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, ReadHandlerInternal, _stream);
var result = await _stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length);
byte[] data = new byte[result];
Buffer.BlockCopy(_receiveBuffer, 0, data, 0, result);
ReadHandler(data, result);
}
catch (Exception ex)
{
@@ -67,28 +77,11 @@ namespace Framework.Networking
}
}
void ReadHandlerInternal(IAsyncResult result)
{
int bytes = 0;
try
{
bytes = _stream.EndRead(result);
}
catch (Exception ex)
{
Log.outException(ex);
}
ReadHandler(bytes);
}
public abstract void ReadHandler(int transferredBytes);
public void AsyncHandshake(X509Certificate2 certificate)
public async Task AsyncHandshake(X509Certificate2 certificate)
{
try
{
_stream.AuthenticateAsServer(certificate, false, System.Security.Authentication.SslProtocols.Tls, false);
await _stream.AuthenticateAsServerAsync(certificate, false, System.Security.Authentication.SslProtocols.Tls, false);
}
catch(Exception ex)
{
@@ -96,17 +89,20 @@ namespace Framework.Networking
CloseSocket();
return;
}
AsyncRead();
await AsyncRead();
}
public void AsyncWrite(byte[] data)
public abstract void ReadHandler(byte[] data, int receivedLength);
public async Task AsyncWrite(byte[] data)
{
if (!IsOpen())
return;
try
{
_stream.Write(data, 0, data.Length);
await _stream.WriteAsync(data, 0, data.Length);
}
catch (Exception ex)
{
@@ -118,39 +114,22 @@ namespace Framework.Networking
{
try
{
_closed = true;
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch (Exception ex)
{
Log.outDebug(LogFilter.Network, "WorldSocket.CloseSocket: {0} errored when shutting down socket: {1}", GetRemoteIpAddress().ToString(), ex.Message);
Log.outDebug(LogFilter.Network, $"WorldSocket.CloseSocket: {GetRemoteIpEndPoint()} errored when shutting down socket: {ex.Message}");
}
OnClose();
}
public virtual void OnClose() { Dispose(); }
public bool IsOpen() { return _socket.Connected; }
public void SetNoDelay(bool enable)
{
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, enable);
}
public virtual void OnClose() { }
public bool IsOpen() { return !_closed; }
public byte[] GetReceiveBuffer()
{
return _receiveBuffer;
}
Socket _socket;
internal SslStream _stream;
byte[] _receiveBuffer;
volatile bool _closed;
IPAddress _remoteAddress;
ushort _remotePort;
}
}
+36 -61
View File
@@ -18,42 +18,50 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace Framework.Networking
{
public interface ISocket
{
void Accept();
bool Update();
bool IsOpen();
void CloseSocket();
}
public abstract class SocketBase : ISocket, IDisposable
{
Socket _socket;
IPEndPoint _remoteIPEndPoint;
byte[] _receiveBuffer;
protected SocketBase(Socket socket)
{
_socket = socket;
_remoteAddress = ((IPEndPoint)_socket.RemoteEndPoint).Address;
_remotePort = (ushort)((IPEndPoint)_socket.RemoteEndPoint).Port;
_remoteIPEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
_receiveBuffer = new byte[ushort.MaxValue];
}
public virtual void Dispose()
{
_receiveBuffer = null;
_socket.Dispose();
}
public abstract void Start();
public abstract void Accept();
public virtual bool Update()
{
return IsOpen();
}
public IPAddress GetRemoteIpAddress()
public IPEndPoint GetRemoteIpAddress()
{
return _remoteAddress;
return _remoteIPEndPoint;
}
public ushort GetRemotePort()
{
return _remotePort;
}
public void AsyncRead()
public async Task AsyncRead()
{
if (!IsOpen())
return;
@@ -63,12 +71,12 @@ namespace Framework.Networking
using (var socketEventargs = new SocketAsyncEventArgs())
{
socketEventargs.SetBuffer(_receiveBuffer, 0, _receiveBuffer.Length);
socketEventargs.Completed += (sender, args) => ReadHandlerInternal(args);
socketEventargs.Completed += async (sender, args) => await ProcessReadAsync(args);
socketEventargs.SocketFlags = SocketFlags.None;
socketEventargs.RemoteEndPoint = _socket.RemoteEndPoint;
if (!_socket.ReceiveAsync(socketEventargs))
ReadHandlerInternal(socketEventargs);
await ProcessReadAsync(socketEventargs);
}
}
catch (Exception ex)
@@ -77,8 +85,7 @@ namespace Framework.Networking
}
}
public delegate void SocketReadCallback(SocketAsyncEventArgs args);
public void AsyncReadWithCallback(SocketReadCallback callback)
public async Task AsyncReadWithCallback(SocketReadCallback callback)
{
if (!IsOpen())
return;
@@ -92,7 +99,7 @@ namespace Framework.Networking
socketEventargs.UserToken = _socket;
socketEventargs.SocketFlags = SocketFlags.None;
if (!_socket.ReceiveAsync(socketEventargs))
callback(socketEventargs);
await callback(socketEventargs);
}
}
catch (Exception ex)
@@ -101,7 +108,7 @@ namespace Framework.Networking
}
}
void ReadHandlerInternal(SocketAsyncEventArgs args)
async Task ProcessReadAsync(SocketAsyncEventArgs args)
{
if (args.SocketError != SocketError.Success)
{
@@ -115,31 +122,19 @@ namespace Framework.Networking
return;
}
ReadHandler(args.BytesTransferred);
byte[] data = new byte[args.BytesTransferred];
Buffer.BlockCopy(_receiveBuffer, 0, data, 0, args.BytesTransferred);
await ReadHandler(data, args.BytesTransferred);
}
public abstract void ReadHandler(int transferredBytes);
public abstract Task ReadHandler(byte[] data, int bytesTransferred);
public void AsyncWrite(byte[] data)
public async void AsyncWrite(byte[] data)
{
if (!IsOpen())
return;
using (var socketEventargs = new SocketAsyncEventArgs())
{
socketEventargs.SetBuffer(data, 0, data.Length);
socketEventargs.Completed += WriteHandlerInternal;
socketEventargs.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventargs.UserToken = _socket;
socketEventargs.SocketFlags = SocketFlags.None;
_socket.SendAsync(socketEventargs);
}
}
void WriteHandlerInternal(object sender, SocketAsyncEventArgs args)
{
args.Completed -= WriteHandlerInternal;
await _socket.SendAsync(data, SocketFlags.None);
}
public void CloseSocket()
@@ -149,46 +144,26 @@ namespace Framework.Networking
try
{
_closed = true;
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch (Exception ex)
{
Log.outDebug(LogFilter.Network, "WorldSocket.CloseSocket: {0} errored when shutting down socket: {1}", GetRemoteIpAddress().ToString(), ex.Message);
Log.outDebug(LogFilter.Network, $"WorldSocket.CloseSocket: {GetRemoteIpAddress()} errored when shutting down socket: {ex.Message}");
}
OnClose();
}
public virtual void OnClose() { Dispose(); }
public bool IsOpen() { return _socket.Connected; }
public void SetNoDelay(bool enable)
{
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, enable);
}
public virtual void OnClose() { Dispose(); }
public bool IsOpen() { return !_closed; }
public byte[] GetReceiveBuffer()
{
return _receiveBuffer;
}
Socket _socket;
byte[] _receiveBuffer;
volatile bool _closed;
IPAddress _remoteAddress;
ushort _remotePort;
}
public interface ISocket
{
void Start();
bool Update();
bool IsOpen();
void CloseSocket();
public delegate Task SocketReadCallback(SocketAsyncEventArgs args);
}
}
+5 -5
View File
@@ -22,6 +22,10 @@ namespace Framework.Networking
{
public class SocketManager<TSocketType> where TSocketType : ISocket
{
public AsyncAcceptor Acceptor;
NetworkThread<TSocketType>[] _threads;
int _threadCount;
public virtual bool StartNetwork(string bindIp, int port, int threadCount = 1)
{
Cypher.Assert(threadCount > 0);
@@ -74,7 +78,7 @@ namespace Framework.Networking
try
{
TSocketType newSocket = (TSocketType)Activator.CreateInstance(typeof(TSocketType), sock);
newSocket.Start();
newSocket.Accept();
_threads[SelectThreadWithMinConnections()].AddSocket(newSocket);
}
@@ -96,9 +100,5 @@ namespace Framework.Networking
return min;
}
public AsyncAcceptor Acceptor;
NetworkThread<TSocketType>[] _threads;
int _threadCount;
}
}
+2 -50
View File
@@ -16,6 +16,7 @@
*/
using Framework.Constants;
using Framework.Realm;
using System;
using System.Net;
using System.Net.Sockets;
@@ -94,7 +95,7 @@ public class Realm : IEquatable<Realm>
return new { ExternalAddress, LocalAddress, LocalSubnetMask, Port, Name, Type, Flags, Timezone, AllowedSecurityLevel, PopulationLevel }.GetHashCode();
}
public RealmHandle Id;
public RealmId Id;
public uint Build;
public IPAddress ExternalAddress;
public IPAddress LocalAddress;
@@ -109,52 +110,3 @@ public class Realm : IEquatable<Realm>
public float PopulationLevel;
}
public struct RealmHandle : IEquatable<RealmHandle>
{
public RealmHandle(byte region, byte battlegroup, uint index)
{
Region = region;
Site = battlegroup;
Realm = index;
}
public RealmHandle(uint realmAddress)
{
Region = (byte)((realmAddress >> 24) & 0xFF);
Site = (byte)((realmAddress >> 16) & 0xFF);
Realm = realmAddress & 0xFFFF;
}
public uint GetAddress()
{
return (uint)((Region << 24) | (Site << 16) | (ushort)Realm);
}
public string GetAddressString()
{
return $"{Region}-{Site}-{Realm}";
}
public string GetSubRegionAddress()
{
return $"{Region}-{Site}-0";
}
public override bool Equals(object obj)
{
return obj != null && obj is RealmHandle && Equals((RealmHandle)obj);
}
public bool Equals(RealmHandle other)
{
return other.Realm == Realm;
}
public override int GetHashCode()
{
return new { Site, Region, Realm }.GetHashCode();
}
public byte Region;
public byte Site;
public uint Realm; // primary key in `realmlist` table
}
+58
View File
@@ -0,0 +1,58 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System;
namespace Framework.Realm
{
public struct RealmId : IEquatable<RealmId>
{
public uint Index { get; set; }
public byte Region { get; set; }
public byte Site { get; set; }
public RealmId(byte region, byte battlegroup, uint index)
{
Region = region;
Site = battlegroup;
Index = index;
}
public RealmId(uint realmAddress)
{
Region = (byte)((realmAddress >> 24) & 0xFF);
Site = (byte)((realmAddress >> 16) & 0xFF);
Index = realmAddress & 0xFFFF;
}
public uint GetAddress()
{
return (uint)((Region << 24) | (Site << 16) | (ushort)Index);
}
public string GetAddressString()
{
return $"{Region}-{Site}-{Index}";
}
public string GetSubRegionAddress()
{
return $"{Region}-{Site}-0";
}
public override bool Equals(object obj)
{
return obj != null && obj is RealmId && Equals((RealmId)obj);
}
public bool Equals(RealmId other)
{
return other.Index == Index;
}
public override int GetHashCode()
{
return new { Site, Region, Index }.GetHashCode();
}
}
}
+12 -11
View File
@@ -17,7 +17,7 @@
using Framework.Constants;
using Framework.Database;
using Framework.Rest;
using Framework.Web;
using Framework.Serialization;
using System;
using System.Collections.Generic;
@@ -25,6 +25,7 @@ using System.Linq;
using System.Net;
using System.Timers;
using System.Collections.Concurrent;
using Framework.Realm;
public class RealmManager : Singleton<RealmManager>
{
@@ -91,7 +92,7 @@ public class RealmManager : Singleton<RealmManager>
{
PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_REALMLIST);
SQLResult result = DB.Login.Query(stmt);
Dictionary<RealmHandle, string> existingRealms = new Dictionary<RealmHandle, string>();
Dictionary<RealmId, string> existingRealms = new Dictionary<RealmId, string>();
foreach (var p in _realms)
existingRealms[p.Key] = p.Value.Name;
@@ -125,11 +126,11 @@ public class RealmManager : Singleton<RealmManager>
byte region = result.Read<byte>(12);
byte battlegroup = result.Read<byte>(13);
realm.Id = new RealmHandle(region, battlegroup, realmId);
realm.Id = new RealmId(region, battlegroup, realmId);
UpdateRealm(realm);
var subRegion = new RealmHandle(region, battlegroup, 0).GetAddressString();
var subRegion = new RealmId(region, battlegroup, 0).GetAddressString();
if (!_subRegions.Contains(subRegion))
_subRegions.Add(subRegion);
@@ -147,7 +148,7 @@ public class RealmManager : Singleton<RealmManager>
Log.outInfo(LogFilter.Realmlist, "Removed realm \"{0}\".", pair.Value);
}
public Realm GetRealm(RealmHandle id)
public Realm GetRealm(RealmId id)
{
return _realms.LookupByKey(id);
}
@@ -177,7 +178,7 @@ public class RealmManager : Singleton<RealmManager>
}
}
public byte[] GetRealmEntryJSON(RealmHandle id, uint build)
public byte[] GetRealmEntryJSON(RealmId id, uint build)
{
byte[] compressed = new byte[0];
Realm realm = GetRealm(id);
@@ -209,7 +210,7 @@ public class RealmManager : Singleton<RealmManager>
}
realmEntry.Version = version;
realmEntry.CfgRealmsID = (int)realm.Id.Realm;
realmEntry.CfgRealmsID = (int)realm.Id.Index;
realmEntry.Flags = (int)realm.Flags;
realmEntry.Name = realm.Name;
realmEntry.CfgConfigsID = (int)realm.GetConfigId();
@@ -256,7 +257,7 @@ public class RealmManager : Singleton<RealmManager>
realmListUpdate.Update.Version.Build = (int)realm.Value.Build;
}
realmListUpdate.Update.CfgRealmsID = (int)realm.Value.Id.Realm;
realmListUpdate.Update.CfgRealmsID = (int)realm.Value.Id.Index;
realmListUpdate.Update.Flags = (int)flag;
realmListUpdate.Update.Name = realm.Value.Name;
realmListUpdate.Update.CfgConfigsID = (int)realm.Value.GetConfigId();
@@ -270,9 +271,9 @@ public class RealmManager : Singleton<RealmManager>
return Json.Deflate("JSONRealmListUpdates", realmList);
}
public BattlenetRpcErrorCode JoinRealm(uint realmAddress, uint build, IPAddress clientAddress, Array<byte> clientSecret, LocaleConstant locale, string os, string accountName, Bgs.Protocol.GameUtilities.V1.ClientResponse response)
public BattlenetRpcErrorCode JoinRealm(uint realmAddress, uint build, IPAddress clientAddress, byte[] clientSecret, Locale locale, string os, string accountName, Bgs.Protocol.GameUtilities.V1.ClientResponse response)
{
Realm realm = GetRealm(new RealmHandle(realmAddress));
Realm realm = GetRealm(new RealmId(realmAddress));
if (realm != null)
{
if (realm.Flags.HasAnyFlag(RealmFlags.Offline) || realm.Build != build)
@@ -328,7 +329,7 @@ public class RealmManager : Singleton<RealmManager>
List<string> GetSubRegions() { return _subRegions; }
List<RealmBuildInfo> _builds = new List<RealmBuildInfo>();
ConcurrentDictionary<RealmHandle, Realm> _realms = new ConcurrentDictionary<RealmHandle, Realm>();
ConcurrentDictionary<RealmId, Realm> _realms = new ConcurrentDictionary<RealmId, Realm>();
List<string> _subRegions = new List<string>();
Timer _updateTimer;
}
@@ -1,41 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class LogonData
{
public string this[string inputId] => Inputs.SingleOrDefault(i => i.Id == inputId)?.Value;
[DataMember(Name = "version")]
public string Version { get; set; }
[DataMember(Name = "program_id")]
public string Program { get; set; }
[DataMember(Name = "platform_id")]
public string Platform { get; set; }
[DataMember(Name = "inputs")]
public List<FormInputValue> Inputs { get; set; } = new List<FormInputValue>();
}
}
-37
View File
@@ -1,37 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class FormInput
{
[DataMember(Name = "input_id")]
public string Id { get; set; }
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "label")]
public string Label { get; set; }
[DataMember(Name = "max_length")]
public int MaxLength { get; set; }
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class FormInputValue
{
[DataMember(Name = "input_id")]
public string Id { get; set; }
[DataMember(Name = "value")]
public string Value { get; set; }
}
}
-35
View File
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class FormInputs
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "prompt")]
public string Prompt { get; set; }
[DataMember(Name = "inputs")]
public List<FormInput> Inputs { get; set; } = new List<FormInput>();
}
}
-31
View File
@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class Address
{
[DataMember(Name = "ip")]
public string Ip { get; set; }
[DataMember(Name = "port")]
public int Port { get; set; }
}
}
@@ -1,32 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class AddressFamily
{
[DataMember(Name = "family")]
public int Id { get; set; }
[DataMember(Name = "addresses")]
public IList<Address> Addresses { get; set; } = new List<Address>();
}
}
@@ -1,37 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class ClientVersion
{
[DataMember(Name = "versionMajor")]
public int Major { get; set; }
[DataMember(Name = "versionBuild")]
public int Build { get; set; }
[DataMember(Name = "versionMinor")]
public int Minor { get; set; }
[DataMember(Name = "versionRevision")]
public int Revision { get; set; }
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmCharacterCountEntry
{
[DataMember(Name = "wowRealmAddress")]
public int WowRealmAddress { get; set; }
[DataMember(Name = "count")]
public int Count { get; set; }
}
}
@@ -1,29 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmCharacterCountList
{
[DataMember(Name = "counts")]
public IList<RealmCharacterCountEntry> Counts { get; set; } = new List<RealmCharacterCountEntry>();
}
}
@@ -1,29 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmListServerIPAddresses
{
[DataMember(Name = "families")]
public IList<AddressFamily> Families { get; set; } = new List<AddressFamily>();
}
}
@@ -1,28 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmListTicketClientInformation
{
[DataMember(Name = "info")]
public RealmListTicketInformation Info { get; set; } = new RealmListTicketInformation();
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmListTicketIdentity
{
[DataMember(Name = "gameAccountID")]
public int GameAccountId { get; set; }
[DataMember(Name = "gameAccountRegion")]
public int GameAccountRegion { get; set; }
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmListUpdate
{
[DataMember(Name = "update")]
public RealmEntry Update { get; set; } = new RealmEntry();
[DataMember(Name = "deleting")]
public bool Deleting { get; set; }
}
}
@@ -1,29 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
{
[DataContract]
public class RealmListUpdates
{
[DataMember(Name = "updates")]
public IList<RealmListUpdate> Updates { get; set; } = new List<RealmListUpdate>();
}
}
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Framework.Web.API
{
public class ApiRequest<T>
{
public uint? SearchId { get; set; }
public Func<T, bool> SearchFunc { get; set; }
}
}
@@ -0,0 +1,27 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class LogonData
{
public string this[string inputId] => Inputs.SingleOrDefault(i => i.Id == inputId)?.Value;
[DataMember(Name = "version")]
public string Version { get; set; }
[DataMember(Name = "program_id")]
public string Program { get; set; }
[DataMember(Name = "platform_id")]
public string Platform { get; set; }
[DataMember(Name = "inputs")]
public List<FormInputValue> Inputs { get; set; } = new List<FormInputValue>();
}
}
@@ -1,23 +1,9 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Rest
namespace Framework.Web
{
[DataContract]
public class LogonResult
@@ -0,0 +1,23 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class FormInput
{
[DataMember(Name = "input_id")]
public string Id { get; set; }
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "label")]
public string Label { get; set; }
[DataMember(Name = "max_length")]
public int MaxLength { get; set; }
}
}
@@ -0,0 +1,17 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class FormInputValue
{
[DataMember(Name = "input_id")]
public string Id { get; set; }
[DataMember(Name = "value")]
public string Value { get; set; }
}
}
@@ -0,0 +1,21 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class FormInputs
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "prompt")]
public string Prompt { get; set; }
[DataMember(Name = "inputs")]
public List<FormInput> Inputs { get; set; } = new List<FormInput>();
}
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class Address
{
[DataMember(Name = "ip")]
public string Ip { get; set; }
[DataMember(Name = "port")]
public int Port { get; set; }
}
}
@@ -0,0 +1,18 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class AddressFamily
{
[DataMember(Name = "family")]
public int Id { get; set; }
[DataMember(Name = "addresses")]
public IList<Address> Addresses { get; set; } = new List<Address>();
}
}
@@ -0,0 +1,23 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class ClientVersion
{
[DataMember(Name = "versionMajor")]
public int Major { get; set; }
[DataMember(Name = "versionBuild")]
public int Build { get; set; }
[DataMember(Name = "versionMinor")]
public int Minor { get; set; }
[DataMember(Name = "versionRevision")]
public int Revision { get; set; }
}
}
@@ -0,0 +1,17 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmCharacterCountEntry
{
[DataMember(Name = "wowRealmAddress")]
public int WowRealmAddress { get; set; }
[DataMember(Name = "count")]
public int Count { get; set; }
}
}
@@ -0,0 +1,15 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmCharacterCountList
{
[DataMember(Name = "counts")]
public IList<RealmCharacterCountEntry> Counts { get; set; } = new List<RealmCharacterCountEntry>();
}
}
@@ -1,23 +1,9 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Rest
namespace Framework.Web
{
[DataContract]
public class RealmEntry
@@ -0,0 +1,15 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmListServerIPAddresses
{
[DataMember(Name = "families")]
public IList<AddressFamily> Families { get; set; } = new List<AddressFamily>();
}
}
@@ -0,0 +1,14 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmListTicketClientInformation
{
[DataMember(Name = "info")]
public RealmListTicketInformation Info { get; set; } = new RealmListTicketInformation();
}
}
@@ -0,0 +1,17 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmListTicketIdentity
{
[DataMember(Name = "gameAccountID")]
public int GameAccountId { get; set; }
[DataMember(Name = "gameAccountRegion")]
public int GameAccountRegion { get; set; }
}
}
@@ -1,24 +1,10 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Rest
namespace Framework.Web
{
[DataContract]
public class RealmListTicketInformation
@@ -0,0 +1,17 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmListUpdate
{
[DataMember(Name = "update")]
public RealmEntry Update { get; set; } = new RealmEntry();
[DataMember(Name = "deleting")]
public bool Deleting { get; set; }
}
}
@@ -0,0 +1,15 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Framework.Web
{
[DataContract]
public class RealmListUpdates
{
[DataMember(Name = "updates")]
public IList<RealmListUpdate> Updates { get; set; } = new List<RealmListUpdate>();
}
}