Commit 17365f29 authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master' into master

parents d9f0c692 ba5985d6
Pipeline #27442 passed with stages
in 1 minute and 52 seconds
......@@ -85,6 +85,7 @@ namespace WindBot.Game
_packets.Add(StocMessage.Chat, OnChat);
_packets.Add(StocMessage.ChangeSide, OnChangeSide);
_packets.Add(StocMessage.ErrorMsg, OnErrorMsg);
_packets.Add(StocMessage.TeammateSurrender, OnTeammateSurrender);
_messages.Add(GameMessage.Retry, OnRetry);
_messages.Add(GameMessage.Start, OnStart);
......@@ -325,6 +326,12 @@ namespace WindBot.Game
//Connection.Close();
}
private void OnTeammateSurrender(BinaryReader packet)
{
Thread.Sleep(500);
Game.Surrender();
}
private void OnRetry(BinaryReader packet)
{
_ai.OnRetry();
......
<?xml version="1.0" encoding="utf-8"?>
<?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>
......@@ -50,15 +50,6 @@
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="YGOSharp.Network">
<HintPath>.\YGOSharp.Network.dll</HintPath>
</Reference>
<Reference Include="YGOSharp.OCGWrapper">
<HintPath>.\YGOSharp.OCGWrapper.dll</HintPath>
</Reference>
<Reference Include="YGOSharp.OCGWrapper.Enums">
<HintPath>.\YGOSharp.OCGWrapper.Enums.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Config.cs" />
......@@ -158,6 +149,29 @@
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WindBotInfo.cs" />
<Compile Include="YGOSharp.Network\BinaryClient.cs" />
<Compile Include="YGOSharp.Network\Enums\CtosMessage.cs" />
<Compile Include="YGOSharp.Network\Enums\GameState.cs" />
<Compile Include="YGOSharp.Network\Enums\PlayerChange.cs" />
<Compile Include="YGOSharp.Network\Enums\PlayerState.cs" />
<Compile Include="YGOSharp.Network\Enums\PlayerType.cs" />
<Compile Include="YGOSharp.Network\Enums\StocMessage.cs" />
<Compile Include="YGOSharp.Network\NetworkClient.cs" />
<Compile Include="YGOSharp.Network\Utils\BinaryExtensions.cs" />
<Compile Include="YGOSharp.Network\YGOClient.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardAttribute.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardLinkMarker.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardLocation.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardPosition.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardRace.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\CardType.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\DuelPhase.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\GameMessage.cs" />
<Compile Include="YGOSharp.OCGWrapper.Enums\Query.cs" />
<Compile Include="YGOSharp.OCGWrapper\Card.cs" />
<Compile Include="YGOSharp.OCGWrapper\CardsManager.cs" />
<Compile Include="YGOSharp.OCGWrapper\NamedCard.cs" />
<Compile Include="YGOSharp.OCGWrapper\NamedCardsManager.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
......@@ -187,4 +201,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace YGOSharp.Network
{
public class BinaryClient
{
public event Action Connected;
public event Action<Exception> Disconnected;
public event Action<BinaryReader> PacketReceived;
protected int MaxPacketLength = 0xFFFF;
protected int HeaderSize = 2;
protected bool IsHeaderSizeIncluded = false;
private NetworkClient _client;
private List<byte> _receiveBuffer = new List<byte>();
private Queue<byte[]> _pendingPackets = new Queue<byte[]>();
private byte[] _lengthBuffer = new byte[16];
private int _pendingLength;
private bool _wasConnected;
private bool _wasDisconnected;
private bool _wasDisconnectedEventFired;
private Exception _closingException;
public bool IsConnected
{
get { return !_wasDisconnectedEventFired; }
}
public IPAddress RemoteIPAddress
{
get { return _client.RemoteIPAddress; }
}
public BinaryClient(NetworkClient client)
{
_client = client;
client.Connected += Client_Connected;
client.Disconnected += Client_Disconnected;
client.DataReceived += Client_DataReceived;
if (_client.IsConnected)
{
_client.BeginReceive();
}
}
public void Connect(IPAddress address, int port)
{
_client.BeginConnect(address, port);
}
public void Initialize(Socket socket)
{
_client.Initialize(socket);
}
public void Update()
{
if (_wasConnected)
{
_wasConnected = false;
Connected?.Invoke();
}
ReceivePendingPackets();
if (_wasDisconnected && !_wasDisconnectedEventFired)
{
_wasDisconnectedEventFired = true;
Disconnected?.Invoke(_closingException);
}
}
public void Send(byte[] packet)
{
if (packet.Length > MaxPacketLength)
{
throw new Exception("Tried to send a too large packet");
}
int packetLength = packet.Length;
if (IsHeaderSizeIncluded) packetLength += HeaderSize;
byte[] header;
if (HeaderSize == 2)
{
header = BitConverter.GetBytes((ushort)packetLength);
}
else if (HeaderSize == 4)
{
header = BitConverter.GetBytes(packetLength);
}
else
{
throw new Exception("Unsupported header size: " + HeaderSize);
}
byte[] data = new byte[packet.Length + HeaderSize];
Array.Copy(header, 0, data, 0, header.Length);
Array.Copy(packet, 0, data, header.Length, packet.Length);
_client.BeginSend(data);
}
public void Close(Exception error = null)
{
_client.Close(error);
}
private void ReceivePendingPackets()
{
bool hasReceived;
do
{
byte[] packet = null;
lock (_pendingPackets)
{
if (_pendingPackets.Count > 0)
{
packet = _pendingPackets.Dequeue();
}
}
hasReceived = false;
if (packet != null)
{
hasReceived = true;
using (MemoryStream stream = new MemoryStream(packet, false))
{
using (BinaryReader reader = new BinaryReader(stream))
{
PacketReceived?.Invoke(reader);
}
}
}
}
while (hasReceived);
}
private void Client_Connected()
{
_wasConnected = true;
}
private void Client_Disconnected(Exception ex)
{
_wasDisconnected = true;
_closingException = ex;
}
private void Client_DataReceived(byte[] data)
{
_receiveBuffer.AddRange(data);
ExtractPackets();
}
private void ExtractPackets()
{
bool hasExtracted;
do
{
if (_pendingLength == 0)
{
hasExtracted = ExtractPendingLength();
}
else
{
hasExtracted = ExtractPendingPacket();
}
}
while (hasExtracted);
}
private bool ExtractPendingLength()
{
if (_receiveBuffer.Count >= HeaderSize)
{
_receiveBuffer.CopyTo(0, _lengthBuffer, 0, HeaderSize);
if (HeaderSize == 2)
{
_pendingLength = BitConverter.ToUInt16(_lengthBuffer, 0);
}
else if (HeaderSize == 4)
{
_pendingLength = BitConverter.ToInt32(_lengthBuffer, 0);
}
else
{
throw new Exception("Unsupported header size: " + HeaderSize);
}
_receiveBuffer.RemoveRange(0, HeaderSize);
if (IsHeaderSizeIncluded) _pendingLength -= HeaderSize;
if (_pendingLength < 0 || _pendingLength > MaxPacketLength)
{
_client.Close(new Exception("Tried to receive a too large packet"));
return false;
}
return true;
}
return false;
}
private bool ExtractPendingPacket()
{
if (_receiveBuffer.Count >= _pendingLength)
{
byte[] packet = new byte[_pendingLength];
_receiveBuffer.CopyTo(0, packet, 0, _pendingLength);
_receiveBuffer.RemoveRange(0, _pendingLength);
_pendingLength = 0;
lock (_pendingPackets)
{
_pendingPackets.Enqueue(packet);
}
return true;
}
return false;
}
}
}
namespace YGOSharp.Network.Enums
{
public enum CtosMessage
{
Response = 0x1,
UpdateDeck = 0x2,
HandResult = 0x3,
TpResult = 0x4,
PlayerInfo = 0x10,
CreateGame = 0x11,
JoinGame = 0x12,
LeaveGame = 0x13,
Surrender = 0x14,
TimeConfirm = 0x15,
Chat = 0x16,
HsToDuelist = 0x20,
HsToObserver = 0x21,
HsReady = 0x22,
HsNotReady = 0x23,
HsKick = 0x24,
HsStart = 0x25
}
}
namespace YGOSharp.Network.Enums
{
public enum GameState
{
Lobby = 0,
Hand = 1,
Starting = 2,
Duel = 3,
End = 4,
Side = 5
}
}
\ No newline at end of file
namespace YGOSharp.Network.Enums
{
public enum PlayerChange
{
Observe = 0x8,
Ready = 0x9,
NotReady = 0xA,
Leave = 0xB
}
}
namespace YGOSharp.Network.Enums
{
public enum PlayerState
{
None = 0,
Response = 1
}
}
\ No newline at end of file
namespace YGOSharp.Network.Enums
{
public enum PlayerType
{
Undefined = -1,
Player1 = 0,
Player2 = 1,
Player3 = 2,
Player4 = 3,
Player5 = 4,
Player6 = 5,
Observer = 7,
Host = 0x10,
Red = 11,
Green = 12,
Blue = 13,
BabyBlue = 14,
Pink = 15,
Yellow = 16,
White = 17,
Gray = 18
}
}
\ No newline at end of file
namespace YGOSharp.Network.Enums
{
public enum StocMessage
{
GameMsg = 0x1,
ErrorMsg = 0x2,
SelectHand = 0x3,
SelectTp = 0x4,
HandResult = 0x5,
TpResult = 0x6,
ChangeSide = 0x7,
WaitingSide = 0x8,
CreateGame = 0x11,
JoinGame = 0x12,
TypeChange = 0x13,
LeaveGame = 0x14,
DuelStart = 0x15,
DuelEnd = 0x16,
Replay = 0x17,
TimeLimit = 0x18,
Chat = 0x19,
HsPlayerEnter = 0x20,
HsPlayerChange = 0x21,
HsWatchChange = 0x22,
TeammateSurrender = 0x23
}
}
using System;
using System.Net;
using System.Net.Sockets;
namespace YGOSharp.Network
{
public class NetworkClient
{
public event Action Connected;
public event Action<Exception> Disconnected;
public event Action<byte[]> DataReceived;
public bool IsConnected { get; private set; }
public IPAddress RemoteIPAddress
{
get { return _endPoint.Address; }
}
private const int BufferSize = 4096;
private Socket _socket;
private IPEndPoint _endPoint;
private bool _isClosed;
private byte[] _receiveBuffer = new byte[BufferSize];
public NetworkClient()
{
}
public NetworkClient(Socket socket)
{
Initialize(socket);
}
public void Initialize(Socket socket)
{
_endPoint = (IPEndPoint)socket.RemoteEndPoint;
_socket = socket;
IsConnected = true;
Connected?.Invoke();
}
public void BeginConnect(IPAddress address, int port)
{
if (!IsConnected && !_isClosed)
{
IsConnected = true;
try
{
_endPoint = new IPEndPoint(address, port);
_socket = new Socket(_endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_socket.BeginConnect(_endPoint, new AsyncCallback(ConnectCallback), null);
}
catch (Exception ex)
{
Close(ex);
}
}
}
public void BeginSend(byte[] data)
{
try
{
_socket.BeginSend(data, 0, data.Length, SocketFlags.None, SendCallback, data.Length);
}
catch (Exception ex)
{
Close(ex);
}
}
public void BeginReceive()
{
try
{
_socket.BeginReceive(_receiveBuffer, 0, _receiveBuffer.Length, SocketFlags.None, ReceiveCallback, null);
}
catch (Exception ex)
{
Close(ex);
}
}
public void Close(Exception error = null)
{
if (!_isClosed)
{
_isClosed = true;
try
{
if (_socket != null)
{
_socket.Close();
}
}
catch (Exception ex)
{
ex = new AggregateException(error, ex);
}
IsConnected = false;
Disconnected?.Invoke(error);
}
}
private void ConnectCallback(IAsyncResult result)
{
try
{
_socket.EndConnect(result);
}
catch (Exception ex)
{
Close(ex);
return;
}
Connected?.Invoke();
BeginReceive();
}
private void SendCallback(IAsyncResult result)
{
try
{
int bytesSent = _socket.EndSend(result);
if (bytesSent != (int)result.AsyncState)
{
Close();
}
}
catch (Exception ex)
{
Close(ex);
}
}
private void ReceiveCallback(IAsyncResult result)
{
int bytesRead;
try
{
bytesRead = _socket.EndReceive(result);
}
catch (Exception ex)
{
Close(ex);
return;
}
if (bytesRead == 0)
{
Close();
return;
}
byte[] data = new byte[bytesRead];
Array.Copy(_receiveBuffer, data, bytesRead);
DataReceived?.Invoke(data);
BeginReceive();
}
}
}
using System;
using System.IO;
using System.Text;
namespace YGOSharp.Network.Utils
{
public static class BinaryExtensions
{
public static void WriteUnicode(this BinaryWriter writer, string text, int len)
{
byte[] unicode = Encoding.Unicode.GetBytes(text);
byte[] result = new byte[len * 2];
int max = len * 2 - 2;
Array.Copy(unicode, result, unicode.Length > max ? max : unicode.Length);
writer.Write(result);
}
public static string ReadUnicode(this BinaryReader reader, int len)
{
byte[] unicode = reader.ReadBytes(len * 2);
string text = Encoding.Unicode.GetString(unicode);
int index = text.IndexOf('\0');
if (index > 0) text = text.Substring(0, index);
return text;
}
public static byte[] ReadToEnd(this BinaryReader reader)
{
return reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
}
}
}
using System.IO;
using YGOSharp.Network.Enums;
namespace YGOSharp.Network
{
public class YGOClient : BinaryClient
{
public YGOClient()
: base(new NetworkClient())
{
}
public YGOClient(NetworkClient client)
: base(client)
{
}
public void Send(BinaryWriter writer)
{
Send(((MemoryStream)writer.BaseStream).ToArray());
}
public void Send(CtosMessage message)
{
using (BinaryWriter writer = new BinaryWriter(new MemoryStream()))
{
writer.Write((byte)message);
Send(writer);
}
}
public void Send(CtosMessage message, int value)
{
using (BinaryWriter writer = new BinaryWriter(new MemoryStream()))
{
writer.Write((byte)message);
writer.Write(value);
Send(writer);
}
}
}
}
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardAttribute
{
Earth = 0x01,
Water = 0x02,
Fire = 0x04,
Wind = 0x08,
Light = 0x10,
Dark = 0x20,
Divine = 0x40,
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardLinkMarker
{
BottomLeft = 0x01,
Bottom = 0x02,
BottomRight = 0x04,
Left = 0x08,
Right = 0x20,
TopLeft = 0x40,
Top = 0x80,
TopRight = 0x100
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardLocation
{
Deck = 0x01,
Hand = 0x02,
MonsterZone = 0x04,
SpellZone = 0x08,
Grave = 0x10,
Removed = 0x20,
Extra = 0x40,
Overlay = 0x80,
Onfield = 0x0C,
FieldZone = 0x100,
PendulumZone = 0x200
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardPosition
{
FaceUpAttack = 0x1,
FaceDownAttack = 0x2,
FaceUpDefence = 0x4,
FaceDownDefence = 0x8,
FaceUp = 0x5,
FaceDown = 0xA,
Attack = 0x3,
Defence = 0xC
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardRace
{
Warrior = 0x1,
SpellCaster = 0x2,
Fairy = 0x4,
Fiend = 0x8,
Zombie = 0x10,
Machine = 0x20,
Aqua = 0x40,
Pyro = 0x80,
Rock = 0x100,
WindBeast = 0x200,
Plant = 0x400,
Insect = 0x800,
Thunder = 0x1000,
Dragon = 0x2000,
Beast = 0x4000,
BestWarrior = 0x8000,
Dinosaur = 0x10000,
Fish = 0x20000,
SeaSerpent = 0x40000,
Reptile = 0x80000,
Psycho = 0x100000,
DivineBeast = 0x200000,
CreatorGod = 0x400000,
Wyrm = 0x800000,
Cyberse = 0x1000000,
Illusion = 0x2000000
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum CardType
{
Monster = 0x1,
Spell = 0x2,
Trap = 0x4,
Normal = 0x10,
Effect = 0x20,
Fusion = 0x40,
Ritual = 0x80,
TrapMonster = 0x100,
Spirit = 0x200,
Union = 0x400,
Dual = 0x800,
Tuner = 0x1000,
Synchro = 0x2000,
Token = 0x4000,
QuickPlay = 0x10000,
Continuous = 0x20000,
Equip = 0x40000,
Field = 0x80000,
Counter = 0x100000,
Flip = 0x200000,
Toon = 0x400000,
Xyz = 0x800000,
Pendulum = 0x1000000,
SpSummon = 0x2000000,
Link = 0x4000000
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum DuelPhase
{
Draw = 0x01,
Standby = 0x02,
Main1 = 0x04,
BattleStart = 0x08,
BattleStep = 0x10,
Damage = 0x20,
DamageCal = 0x40,
Battle = 0x80,
Main2 = 0x100,
End = 0x200
}
}
namespace YGOSharp.OCGWrapper.Enums
{
public enum GameMessage
{
Retry = 1,
Hint = 2,
Waiting = 3,
Start = 4,
Win = 5,
UpdateData = 6,
UpdateCard = 7,
RequestDeck = 8,
SelectBattleCmd = 10,
SelectIdleCmd = 11,
SelectEffectYn = 12,
SelectYesNo = 13,
SelectOption = 14,
SelectCard = 15,
SelectChain = 16,
SelectPlace = 18,
SelectPosition = 19,
SelectTribute = 20,
SortChain = 21,
SelectCounter = 22,
SelectSum = 23,
SelectDisfield = 24,
SortCard = 25,
SelectUnselect = 26,
ConfirmDecktop = 30,
ConfirmCards = 31,
ShuffleDeck = 32,
ShuffleHand = 33,
RefreshDeck = 34,
SwapGraveDeck = 35,
ShuffleSetCard = 36,
ReverseDeck = 37,
DeckTop = 38,
ShuffleExtra = 39,
NewTurn = 40,
NewPhase = 41,
ConfirmExtratop = 42,
Move = 50,
PosChange = 53,
Set = 54,
Swap = 55,
FieldDisabled = 56,
Summoning = 60,
Summoned = 61,
SpSummoning = 62,
SpSummoned = 63,
FlipSummoning = 64,
FlipSummoned = 65,
Chaining = 70,
Chained = 71,
ChainSolving = 72,
ChainSolved = 73,
ChainEnd = 74,
ChainNegated = 75,
ChainDisabled = 76,
CardSelected = 80,
RandomSelected = 81,
BecomeTarget = 83,
Draw = 90,
Damage = 91,
Recover = 92,
Equip = 93,
LpUpdate = 94,
Unequip = 95,
CardTarget = 96,
CancelTarget = 97,
PayLpCost = 100,
AddCounter = 101,
RemoveCounter = 102,
Attack = 110,
Battle = 111,
AttackDisabled = 112,
DamageStepStart = 113,
DamageStepEnd = 114,
MissedEffect = 120,
BeChainTarget = 121,
CreateRelation = 122,
ReleaseRelation = 123,
TossCoin = 130,
TossDice = 131,
RockPaperScissors = 132,
HandResult = 133,
AnnounceRace = 140,
AnnounceAttrib = 141,
AnnounceCard = 142,
AnnounceNumber = 143,
CardHint = 160,
TagSwap = 161,
ReloadField = 162,
AiName = 163,
ShowHint = 164,
PlayerHint = 165,
MatchKill = 170,
CustomMsg = 180,
DuelWinner = 200
}
}
\ No newline at end of file
namespace YGOSharp.OCGWrapper.Enums
{
public enum Query
{
Code = 0x01,
Position = 0x02,
Alias = 0x04,
Type = 0x08,
Level = 0x10,
Rank = 0x20,
Attribute = 0x40,
Race = 0x80,
Attack = 0x100,
Defence = 0x200,
BaseAttack = 0x400,
BaseDefence = 0x800,
Reason = 0x1000,
ReasonCard = 0x2000,
EquipCard = 0x4000,
TargetCard = 0x8000,
OverlayCard = 0x10000,
Counters = 0x20000,
Owner = 0x40000,
Status = 0x80000,
LScale = 0x200000,
RScale = 0x400000,
Link = 0x800000
}
}
\ No newline at end of file
using YGOSharp.OCGWrapper.Enums;
using System.Data;
namespace YGOSharp.OCGWrapper
{
public class Card
{
public struct CardData
{
public int Code;
public int Alias;
public long Setcode;
public int Type;
public int Level;
public int Attribute;
public int Race;
public int Attack;
public int Defense;
public int LScale;
public int RScale;
public int LinkMarker;
}
public int Id { get; private set; }
public int Ot { get; private set; }
public int Alias { get; private set; }
public long Setcode { get; private set; }
public int Type { get; private set; }
public int Level { get; private set; }
public int LScale { get; private set; }
public int RScale { get; private set; }
public int LinkMarker { get; private set; }
public int Attribute { get; private set; }
public int Race { get; private set; }
public int Attack { get; private set; }
public int Defense { get; private set; }
internal CardData Data { get; private set; }
public static Card Get(int id)
{
return CardsManager.GetCard(id);
}
public bool HasType(CardType type)
{
return ((Type & (int)type) != 0);
}
public bool HasSetcode(int setcode)
{
long setcodes = Setcode;
int settype = setcode & 0xfff;
int setsubtype = setcode & 0xf000;
while (setcodes > 0)
{
long check_setcode = setcodes & 0xffff;
setcodes >>= 16;
if ((check_setcode & 0xfff) == settype && (check_setcode & 0xf000 & setsubtype) == setsubtype) return true;
}
return false;
}
public bool IsExtraCard()
{
return (HasType(CardType.Fusion) || HasType(CardType.Synchro) || HasType(CardType.Xyz) || HasType(CardType.Link));
}
internal Card(IDataRecord reader)
{
Id = reader.GetInt32(0);
Ot = reader.GetInt32(1);
Alias = reader.GetInt32(2);
Setcode = reader.GetInt64(3);
Type = reader.GetInt32(4);
int levelInfo = reader.GetInt32(5);
Level = levelInfo & 0xff;
LScale = (levelInfo >> 24) & 0xff;
RScale = (levelInfo >> 16) & 0xff;
Race = reader.GetInt32(6);
Attribute = reader.GetInt32(7);
Attack = reader.GetInt32(8);
Defense = reader.GetInt32(9);
if (HasType(CardType.Link))
{
LinkMarker = Defense;
Defense = 0;
}
Data = new CardData()
{
Code = Id,
Alias = Alias,
Setcode = Setcode,
Type = Type,
Level = Level,
Attribute = Attribute,
Race = Race,
Attack = Attack,
Defense = Defense,
LScale = LScale,
RScale = RScale,
LinkMarker = LinkMarker
};
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Data;
using Mono.Data.Sqlite;
namespace YGOSharp.OCGWrapper
{
internal static class CardsManager
{
private static IDictionary<int, Card> _cards;
internal static void Init(string databaseFullPath)
{
_cards = new Dictionary<int, Card>();
using (SqliteConnection connection = new SqliteConnection("Data Source=" + databaseFullPath))
{
connection.Open();
using (IDbCommand command = new SqliteCommand("SELECT id, ot, alias, setcode, type, level, race, attribute, atk, def FROM datas", connection))
{
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
LoadCard(reader);
}
}
}
}
}
internal static Card GetCard(int id)
{
if (_cards.ContainsKey(id))
return _cards[id];
return null;
}
private static void LoadCard(IDataRecord reader)
{
Card card = new Card(reader);
_cards.Add(card.Id, card);
}
}
}
\ No newline at end of file
using System.Data;
namespace YGOSharp.OCGWrapper
{
public class NamedCard : Card
{
public string Name { get; private set; }
public string Description { get; private set; }
internal NamedCard(IDataRecord reader) : base(reader)
{
Name = reader.GetString(10);
Description = reader.GetString(11);
}
public static new NamedCard Get(int id)
{
return NamedCardsManager.GetCard(id);
}
}
}
using System.Collections.Generic;
using System.Data;
using Mono.Data.Sqlite;
using System;
using System.IO;
using System.Linq;
namespace YGOSharp.OCGWrapper
{
public static class NamedCardsManager
{
private static IDictionary<int, NamedCard> _cards;
public static void Init(string databaseFullPath)
{
try
{
if (!File.Exists(databaseFullPath))
{
throw new Exception("Could not find the cards database.");
}
_cards = new Dictionary<int, NamedCard>();
using (SqliteConnection connection = new SqliteConnection("Data Source=" + databaseFullPath))
{
connection.Open();
using (IDbCommand command = new SqliteCommand(
"SELECT datas.id, ot, alias, setcode, type, level, race, attribute, atk, def, texts.name, texts.desc"
+ " FROM datas INNER JOIN texts ON datas.id = texts.id",
connection))
{
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
LoadCard(reader);
}
}
}
}
}
catch (Exception ex)
{
throw new Exception("Could not initialize the cards database. Check the inner exception for more details.", ex);
}
}
internal static NamedCard GetCard(int id)
{
if (_cards.ContainsKey(id))
return _cards[id];
return null;
}
public static IList<NamedCard> GetAllCards()
{
return _cards.Values.ToList();
}
private static void LoadCard(IDataRecord reader)
{
NamedCard card = new NamedCard(reader);
_cards.Add(card.Id, card);
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment