using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; namespace Percy { #region DoNotCareAboutThis class Deck { public List Main = new List(); public List Extra = new List(); public List Side = new List(); } class Package { public int Fuction = 0; public BinaryMaster Data = null; public Package() { Fuction = (int)0; Data = new BinaryMaster(); } } class BinaryMaster { MemoryStream memstream = null; public BinaryReader reader = null; public BinaryWriter writer = null; public BinaryMaster(byte[] raw = null) { if (raw == null) { memstream = new MemoryStream(); } else { memstream = new MemoryStream(raw); } reader = new BinaryReader(memstream); writer = new BinaryWriter(memstream); } public void set(byte[] raw) { memstream = new MemoryStream(raw); reader = new BinaryReader(memstream); writer = new BinaryWriter(memstream); } public byte[] get() { byte[] bytes = memstream.ToArray(); return bytes; } public int getLength() { return (int)memstream.Length; } public override string ToString() { string return_value = ""; byte[] bytes = get(); for (int i = 0; i < bytes.Length; i++) { return_value += ((int)bytes[i]).ToString(); if (i < bytes.Length - 1) return_value += ","; } return return_value; } } class BinaryExtensions { public static byte[] ReadToEnd(BinaryReader reader) { return reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); } } 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, SelectUnselectCard = 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, AttackDiabled = 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, } enum CardLocation { Deck = 0x01, Hand = 0x02, MonsterZone = 0x04, SpellZone = 0x08, Grave = 0x10, Removed = 0x20, Extra = 0x40, Overlay = 0x80, Onfield = 0x0C } enum CardPosition { FaceUpAttack = 0x1, FaceDownAttack = 0x2, FaceUpDefence = 0x4, FaceDownDefence = 0x8, FaceUp = 0x5, FaceDown = 0xA, Attack = 0x3, Defence = 0xC } public struct CardData { public int Code; public int Alias; public UInt64 Setcode; public UInt64 _Setcode1; public UInt64 _Setcode2; public UInt64 _Setcode3; 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 RuleCode; } public struct ScriptData { public IntPtr buffer; public int len; } unsafe static class dll { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate IntPtr ScriptReader(String scriptName, Int32* len); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate UInt32 CardReader(UInt32 code, CardData* pData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate UInt32 MessageHandler(IntPtr pDuel, UInt32 messageType); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] static extern void set_card_reader(CardReader f); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] static extern void set_message_handler(MessageHandler f); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] static extern void set_script_reader(ScriptReader f); static smallYgopro.cardHandler card_handler; public static void set_card_api(smallYgopro.cardHandler h) { card_handler = h; set_card_reader(OnCardReader); } static smallYgopro.scriptHandler script_handler; public static void set_script_api(smallYgopro.scriptHandler h) { script_handler = h; set_script_reader(OnScriptHandler); } private static IntPtr OnScriptHandler(string scriptName, int* len) { ScriptData ret = script_handler(scriptName); *len = ret.len; return ret.buffer; } static smallYgopro.chatHandler chat_handler; public static void set_chat_api(smallYgopro.chatHandler h) { chat_handler = h; set_message_handler(OnMessageHandler); } private static UInt32 OnCardReader(UInt32 code, CardData* pData) { *pData = card_handler(code); return code; } static IntPtr _buffer_2 = Marshal.AllocHGlobal(65536); private static UInt32 OnMessageHandler(IntPtr pDuel, UInt32 messageType) { byte[] arr = new byte[256]; get_log_message(pDuel, _buffer_2); Marshal.Copy(_buffer_2, arr, 0, 256); string message = System.Text.Encoding.UTF8.GetString(arr); if (message.Contains("\0")) message = message.Substring(0, message.IndexOf('\0')); chat_handler(message); return 0; } [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr create_duel(UInt32 seed); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr create_duel_v2(UInt32[] seeds); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void start_duel(IntPtr pduel, UInt32 options); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 get_ai_going_first_second(IntPtr pduel, IntPtr deckname); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 set_player_going_first_second(IntPtr pduel, Int32 first, IntPtr deckname); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void set_ai_id(IntPtr pduel, int playerid); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void end_duel(IntPtr pduel); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void set_player_info(IntPtr pduel, Int32 playerid, Int32 lp, Int32 startcount, Int32 drawcount); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void new_card(IntPtr pduel, UInt32 code, Byte owner, Byte playerid, Byte location, Byte sequence, Byte position); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void new_tag_card(IntPtr pduel, UInt32 code, Byte owner, Byte location); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 process(IntPtr pduel); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 get_message(IntPtr pduel, IntPtr buf); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void get_log_message(IntPtr pduel, IntPtr buf); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void set_responseb(IntPtr pduel, IntPtr buf); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void set_responsei(IntPtr pduel, UInt32 value); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 query_card(IntPtr pduel, Byte playerid, Byte location, Byte sequence, Int32 queryFlag, IntPtr buf, Int32 useCache); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 query_field_count(IntPtr pduel, Byte playerid, Byte location); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 query_field_card(IntPtr pduel, Byte playerid, Byte location, Int32 queryFlag, IntPtr buf, Int32 useCache); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 query_field_info(IntPtr pduel, IntPtr buf); [DllImport("ocgcore", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern Int32 preload_script(IntPtr pduel, IntPtr script); } #endregion public class smallYgopro { #region DoNotCareAboutThis //public public delegate CardData cardHandler(long code); public delegate ScriptData scriptHandler(string name); public delegate void chatHandler(string str); chatHandler cast; public Action m_log; void DebugLog(string obj) { if (m_log != null) { m_log(obj); } } public smallYgopro(Action HowToSendBufferToPlayer,cardHandler HowToReadCard, scriptHandler HowToReadScript,chatHandler HowToShowLog) { sendToPlayer = HowToSendBufferToPlayer; dll.set_card_api(HowToReadCard); dll.set_script_api(HowToReadScript); dll.set_chat_api(HowToShowLog); cast = HowToShowLog; Random ran = new Random(Environment.TickCount); duel = dll.create_duel((UInt32)ran.Next(100, 99999)); } public void dispose() { dll.end_duel(duel); Random ran = new Random(Environment.TickCount); duel =dll.create_duel((UInt32)ran.Next(100, 99999)); } public bool startPuzzle(System.String path) { godMode = true; isFirst = true; dll.set_player_info(duel, 0, 8000, 5, 1); dll.set_player_info(duel, 1, 8000, 5, 1); dll.preload_script(duel, getPtrString(path)); dll.start_duel(duel, 0); Refresh(); (new Thread(Process)).Start(); return true; } public bool startAI(string playerDek, string aiDeck, string aiScript, bool playerGoFirst, bool unrand, int life, bool god,int mr) { godMode = god; isFirst = playerGoFirst; dll.set_player_info(duel, 0, life, 5, 1); dll.set_player_info(duel, 1, life, 5, 1); dll.preload_script(duel, getPtrString(aiScript)); addDeck(playerDek, (playerGoFirst ? 0 : 1), !unrand); addDeck(aiDeck, (playerGoFirst ? 1 : 0), true); dll.set_ai_id(duel, playerGoFirst ? 1 : 0); UInt32 opt = 0; opt |= 0x80; if (unrand) { opt |= 0x10; } BinaryMaster master = new BinaryMaster(); master.writer.Write((char)GameMessage.Start); master.writer.Write((byte)(playerGoFirst ? 0xf0 : 0xff)); master.writer.Write((int)life); master.writer.Write((int)life); master.writer.Write((UInt16)dll.query_field_count(duel, 0, 0x1)); master.writer.Write((UInt16)dll.query_field_count(duel, 0, 0x40)); master.writer.Write((UInt16)dll.query_field_count(duel, 1, 0x1)); master.writer.Write((UInt16)dll.query_field_count(duel, 1, 0x40)); sendToPlayer(master.get()); dll.start_duel(duel, opt | (UInt32)(mr << 16)); Refresh(); (new Thread(Process)).Start(); return true; } public void response(byte[] resp) { if (resp.Length > 64) return; IntPtr buf = Marshal.AllocHGlobal(64); Marshal.Copy(resp, 0, buf, resp.Length); dll.set_responseb(duel, buf); Marshal.FreeHGlobal(buf); (new Thread(Process)).Start(); } //private private IntPtr _buffer = Marshal.AllocHGlobal(4096); private IntPtr duel = default(IntPtr); private Action sendToPlayer; private bool godMode = false; private IntPtr getPtrString(string path) { byte[] s = System.Text.Encoding.UTF8.GetBytes(path); IntPtr ptrFileName = Marshal.AllocHGlobal(s.Length + 1); Marshal.Copy(s, 0, ptrFileName, s.Length); Marshal.WriteByte(ptrFileName, s.Length, 0); return ptrFileName; } private Deck FromYDKtoDeck(string path) { Deck deck = new Deck(); try { string text = System.IO.File.ReadAllText(path); string st = text.Replace("\r", ""); string[] lines = st.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); int flag = -1; foreach (string line in lines) { if (line == "#main") { flag = 1; } else if (line == "#extra") { flag = 2; } else if (line == "!side") { flag = 3; } else { int code = 0; try { code = Int32.Parse(line); } catch (Exception) { } if (code > 100) { switch (flag) { case 1: { deck.Main.Add(code); } break; case 2: { deck.Extra.Add(code); } break; case 3: { deck.Side.Add(code); } break; default: break; } } } } } catch (Exception e) { } return deck; } private void addDeck(string playerDek, int playerId, bool rand) { var deck_player = FromYDKtoDeck(playerDek); if (rand) { System.Random seed = new System.Random(); for (int i = 0; i < deck_player.Main.Count; i++) { int random_index = seed.Next() % deck_player.Main.Count; var t = deck_player.Main[i]; deck_player.Main[i] = deck_player.Main[random_index]; deck_player.Main[random_index] = t; } } for (int i = deck_player.Main.Count - 1; i >= 0; i--) { dll.new_card(duel, (uint)deck_player.Main[i], (byte)playerId, (byte)playerId, (byte)CardLocation.Deck, 0, (byte)CardPosition.FaceDownDefence); } for (int i = 0; i < deck_player.Extra.Count; i++) { dll.new_card(duel, (uint)deck_player.Extra[i], (byte)playerId, (byte)playerId, (byte)CardLocation.Extra, 0, (byte)CardPosition.FaceDownDefence); } } void sendToYrp(byte[] buffer) { yrp3dbuilder.Write(buffer[0]); yrp3dbuilder.Write(buffer.Length-1); for (int i = 1; i < buffer.Length; i++) { yrp3dbuilder.Write(buffer[i]); } } BinaryWriter yrp3dbuilder; public byte[] getYRP3dBuffer(YRP yrp) { var tempS = sendToPlayer; sendToPlayer = sendToYrp; MemoryStream stream = new MemoryStream(); yrp3dbuilder = new BinaryWriter(stream); sendToPlayer(yrp.getNamePacket()); dll.end_duel(duel); if (yrp.ID == 0x32707279) // REPLAY_ID_YRP2 { duel = dll.create_duel_v2(yrp.SeedsV2); } else { Meisui.Random.MersenneTwister mtrnd = new Meisui.Random.MersenneTwister(yrp.Seed); duel = dll.create_duel(mtrnd.genrand_Int32()); } godMode = true; isFirst = true; dll.set_player_info(duel, 0, yrp.StartLp, yrp.StartHand, yrp.DrawCount); dll.set_player_info(duel, 1, yrp.StartLp, yrp.StartHand, yrp.DrawCount); if (yrp.playerData.Count == 4) { foreach (var item in yrp.playerData[0].main) { dll.new_card(duel, (uint)item, (byte)0, (byte)0, (byte)CardLocation.Deck, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[0].extra) { dll.new_card(duel, (uint)item, (byte)0, (byte)0, (byte)CardLocation.Extra, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[1].main) { dll.new_tag_card(duel, (uint)item, (byte)0, (byte)CardLocation.Deck); } foreach (var item in yrp.playerData[1].extra) { dll.new_tag_card(duel, (uint)item, (byte)0, (byte)CardLocation.Extra); } foreach (var item in yrp.playerData[2].main) { dll.new_card(duel, (uint)item, (byte)1, (byte)1, (byte)CardLocation.Deck, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[2].extra) { dll.new_card(duel, (uint)item, (byte)1, (byte)1, (byte)CardLocation.Extra, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[3].main) { dll.new_tag_card(duel, (uint)item, (byte)1, (byte)CardLocation.Deck); } foreach (var item in yrp.playerData[3].extra) { dll.new_tag_card(duel, (uint)item, (byte)1, (byte)CardLocation.Extra); } } else { foreach (var item in yrp.playerData[0].main) { dll.new_card(duel, (uint)item, (byte)0, (byte)0, (byte)CardLocation.Deck, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[0].extra) { dll.new_card(duel, (uint)item, (byte)0, (byte)0, (byte)CardLocation.Extra, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[1].main) { dll.new_card(duel, (uint)item, (byte)1, (byte)1, (byte)CardLocation.Deck, 0, (byte)CardPosition.FaceDownDefence); } foreach (var item in yrp.playerData[1].extra) { dll.new_card(duel, (uint)item, (byte)1, (byte)1, (byte)CardLocation.Extra, 0, (byte)CardPosition.FaceDownDefence); } } BinaryMaster master = new BinaryMaster(); master.writer.Write((char)GameMessage.Start); master.writer.Write((byte)0); master.writer.Write((byte)(yrp.opt >> 16)); master.writer.Write(yrp.StartLp); master.writer.Write(yrp.StartLp); master.writer.Write((UInt16)dll.query_field_count(duel, 0, 0x1)); master.writer.Write((UInt16)dll.query_field_count(duel, 0, 0x40)); master.writer.Write((UInt16)dll.query_field_count(duel, 1, 0x1)); master.writer.Write((UInt16)dll.query_field_count(duel, 1, 0x40)); sendToPlayer(master.get()); dll.start_duel(duel, yrp.opt); Refresh(); end = false; err = false; try { while (true) { //log("process"); Process(); if (yrp.gameData.Count==0) { break; } if (yrp.gameData[0].Length > 64) break; IntPtr buf = Marshal.AllocHGlobal(64); Marshal.Copy(yrp.gameData[0], 0, buf, yrp.gameData[0].Length); dll.set_responseb(duel, buf); Marshal.FreeHGlobal(buf); DebugLog("Push: "+BitConverter.ToString(yrp.gameData[0])); yrp.gameData.RemoveAt(0); if (end) { break; } } } catch (Exception) { } if (err) { if (cast != null) { cast("Error Occurred."); } } dispose(); sendToPlayer = tempS; yrp3dbuilder.Close(); stream.Close(); return stream.ToArray(); } #endregion //you can edit all codes safely after this line //the HintInGame will be showed in ai mode window public static string HintInGame = "PercyAI Pro2Team 1033.D"; void Process() { while (true) { int result =dll.process(duel); int len = result & 0xFFFF; if (len > 0) { byte[] arr = new byte[4096]; dll.get_message(duel, _buffer); Marshal.Copy(_buffer, arr, 0, 4096); bool breakOut = false; MemoryStream stream = new MemoryStream(arr); BinaryReader reader = new BinaryReader(stream); while (stream.Position < len) { //log("Analyse"); breakOut = Analyse(reader); } if (breakOut) { break; } } //else //{ // log("len == 0"); // end = true; // break; //} } } BinaryReader currentReader; BinaryWriter currentWriter; int move(int length, bool erase = false) { int returnValue = 0; if (length > 0) { if (currentReader != null) { if (currentWriter != null) { try { byte[] readed = currentReader.ReadBytes(length); if (readed.Length > 0) { returnValue = readed[0]; } if (erase) { for (int i = 0; i < length; i++) { currentWriter.Write((byte)0); } } else { currentWriter.Write(readed); } } catch (Exception e) { } } } } return returnValue; } void flush() { sendToPlayer(((MemoryStream)currentWriter.BaseStream).ToArray()); } bool isFirst = true; int localPlayer(int p) { if (isFirst) { return p; } else { return 1 - p; } } void Refresh() { if (godMode) { RefreshMonsters(0); RefreshMonsters(1); RefreshSpells(0); RefreshSpells(1); RefreshHand(0); RefreshHand(1); RefreshGrave(0); RefreshGrave(1); RefreshExtra(0); RefreshExtra(1); RefreshDeck(0); RefreshDeck(1); RefreshRemoved(0); RefreshRemoved(1); } else { if (isFirst) { RefreshMonsters(0); RefreshMonsters(1); RefreshSpells(0); RefreshSpells(1); RefreshGrave(0); RefreshGrave(1); RefreshHand(0); RefreshExtra(0); RefreshRemoved(0); } else { RefreshMonsters(0); RefreshMonsters(1); RefreshSpells(0); RefreshSpells(1); RefreshGrave(0); RefreshGrave(1); RefreshHand(1); RefreshExtra(1); RefreshRemoved(1); } } } byte[] QueryFieldCard(int player, CardLocation location, int flag, bool useCache) { int len =dll.query_field_card(duel, (byte)player, (byte)location, flag, _buffer, useCache ? 1 : 0); byte[] result = new byte[len]; Marshal.Copy(_buffer, result, 0, len); return result; } void RefreshMonsters(int player, int flag = 0x81fff | 0x10000) { byte[] result = QueryFieldCard(player, CardLocation.MonsterZone, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.MonsterZone); MemoryStream ms = new MemoryStream(result); BinaryReader reader = new BinaryReader(ms); for (int i = 0; i < 7; i++) { int len = reader.ReadInt32(); if (len == 4) { binary.writer.Write(4); continue; } byte[] raw = reader.ReadBytes(len - 4); if ((raw[11] & (int)CardPosition.FaceDown) != 0 && godMode == false && localPlayer(player) != 0) { binary.writer.Write(8); binary.writer.Write(0); } else { binary.writer.Write(len); binary.writer.Write(raw); } } sendToPlayer(binary.get()); } void RefreshSpells(int player, int flag = 0x681fff) { byte[] result = QueryFieldCard(player, CardLocation.SpellZone, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.SpellZone); MemoryStream ms = new MemoryStream(result); BinaryReader reader = new BinaryReader(ms); for (int i = 0; i < 8; i++) { int len = reader.ReadInt32(); if (len == 4) { binary.writer.Write(4); continue; } byte[] raw = reader.ReadBytes(len - 4); if ((raw[11] & (int)CardPosition.FaceDown) != 0 && godMode == false && localPlayer(player) != 0) { binary.writer.Write(8); binary.writer.Write(0); } else { binary.writer.Write(len); binary.writer.Write(raw); } } sendToPlayer(binary.get()); } void RefreshHand(int player, int flag = 0x181fff) { byte[] result = QueryFieldCard(player, CardLocation.Hand, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.Hand); binary.writer.Write(result); sendToPlayer(binary.get()); } void RefreshGrave(int player, int flag = 0x81fff) { byte[] result = QueryFieldCard(player, CardLocation.Grave, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.Grave); binary.writer.Write(result); sendToPlayer(binary.get()); } void RefreshDeck(int player, int flag = 0x81fff) { byte[] result = QueryFieldCard(player, CardLocation.Deck, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.Deck); binary.writer.Write(result); sendToPlayer(binary.get()); } void RefreshExtra(int player, int flag = 0x81fff) { byte[] result = QueryFieldCard(player, CardLocation.Extra, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.Extra); binary.writer.Write(result); sendToPlayer(binary.get()); } void RefreshRemoved(int player, int flag = 0x81fff) { byte[] result = QueryFieldCard(player, CardLocation.Removed, flag, false); var binary = new BinaryMaster(); binary.writer.Write((byte)GameMessage.UpdateData); binary.writer.Write((byte)player); binary.writer.Write((byte)CardLocation.Removed); binary.writer.Write(result); sendToPlayer(binary.get()); } bool end = false; bool err = false; bool Analyse(BinaryReader reader) { bool returnValue = false; currentReader = reader; MemoryStream me = new MemoryStream(); currentWriter = new BinaryWriter(me); int player = 0; int count = 0; GameMessage mes = (GameMessage)move(1); //log(mes.ToString()); switch (mes) { case GameMessage.Retry: returnValue = true; err = true; //end = true; break; case GameMessage.Hint: move(6); break; case GameMessage.Waiting: break; case GameMessage.Start: break; case GameMessage.Win: move(2); returnValue = true; end = true; break; case GameMessage.UpdateData: break; case GameMessage.UpdateCard: break; case GameMessage.RequestDeck: break; case GameMessage.SelectBattleCmd: move(1); move(move(1) * 11); move(move(1) * 8 + 2); returnValue = true; break; case GameMessage.SelectIdleCmd: move(1); move(move(1) * 7); move(move(1) * 7); move(move(1) * 7); move(move(1) * 7); move(move(1) * 7); move(move(1) * 11 + 3); returnValue = true; break; case GameMessage.SelectEffectYn: move(13); returnValue = true; break; case GameMessage.SelectYesNo: move(5); returnValue = true; break; case GameMessage.SelectOption: move(1); move(move(1) * 4); returnValue = true; break; case GameMessage.SelectTribute: case GameMessage.SelectCard: player = move(1); move(3); count = move(1); for (int i = 0; i < count; i++) { int code = currentReader.ReadInt32(); int p = currentReader.ReadByte(); currentWriter.Write(((int)(p == player ? code : 0))); currentWriter.Write((byte)p); move(3); } returnValue = true; break; case GameMessage.SelectUnselectCard: player = move(1); int buttonok = move(1); move(3); int count1 = move(1); for (int i = 0; i < count1; i++) { int code = currentReader.ReadInt32(); int p = currentReader.ReadByte(); currentWriter.Write(((int)(p == player ? code : 0))); currentWriter.Write((byte)p); move(3); } int count2 = move(1); for (int i = 0; i < count2; i++) { int code = currentReader.ReadInt32(); int p = currentReader.ReadByte(); currentWriter.Write(((int)(p == player ? code : 0))); currentWriter.Write((byte)p); move(3); } returnValue = true; break; case GameMessage.SelectChain: move(1); count = move(1); move(1); move(4); move(4); for (int i = 0; i < count; i++) { move(1); move(1); move(4); move(4); move(4); } returnValue = true; break; case GameMessage.SelectDisfield: case GameMessage.SelectPlace: case GameMessage.SelectPosition: move(6); returnValue = true; break; case GameMessage.SelectCounter: move(5); move(move(1) * 9); returnValue = true; break; case GameMessage.SelectSum: move(8); move(move(1) * 11); move(move(1) * 11); returnValue = true; break; case GameMessage.SortChain: case GameMessage.SortCard: move(1); move(move(1) * 7); returnValue = true; break; case GameMessage.ConfirmDecktop: move(1); move(move(1) * 7); break; case GameMessage.ConfirmCards: move(1); move(1); move(move(1) * 7); break; case GameMessage.RefreshDeck: case GameMessage.ShuffleDeck: move(1); break; case GameMessage.ShuffleHand: move(1); move(move(1) * 4); break; case GameMessage.SwapGraveDeck: move(1); break; case GameMessage.ShuffleSetCard: move(1); move(move(1) * 8); break; case GameMessage.ReverseDeck: break; case GameMessage.DeckTop: move(6); break; case GameMessage.NewTurn: move(1); break; case GameMessage.NewPhase: move(2); break; case GameMessage.Move: byte[] raw = currentReader.ReadBytes(16); int pc = raw[4]; int pl = raw[5]; int cc = raw[8]; int cl = raw[9]; int cs = raw[10]; int cp = raw[11]; if (!Convert.ToBoolean((cl & ((int)CardLocation.Grave + (int)CardLocation.Overlay))) && Convert.ToBoolean((cl & ((int)CardLocation.Deck + (int)CardLocation.Hand))) || Convert.ToBoolean((cp & (int)CardPosition.FaceDown))) { raw[0] = 0; raw[1] = 0; raw[2] = 0; raw[3] = 0; } currentWriter.Write(raw); break; case GameMessage.PosChange: move(9); break; case GameMessage.Set: move(4, true); move(4); break; case GameMessage.Swap: move(16); break; case GameMessage.FieldDisabled: move(4); break; case GameMessage.Summoning: move(8); break; case GameMessage.Summoned: break; case GameMessage.SpSummoning: move(8); break; case GameMessage.SpSummoned: break; case GameMessage.FlipSummoning: move(8); break; case GameMessage.FlipSummoned: break; case GameMessage.Chaining: move(16); break; case GameMessage.Chained: move(1); break; case GameMessage.ChainSolving: move(1); break; case GameMessage.ChainSolved: move(1); break; case GameMessage.ChainEnd: break; case GameMessage.ChainNegated: case GameMessage.ChainDisabled: move(1); break; case GameMessage.CardSelected: move(1); move(move(1) * 4); break; case GameMessage.RandomSelected: move(1); move(move(1) * 4); break; case GameMessage.BecomeTarget: move(move(1) * 4); break; case GameMessage.Draw: player = move(1); count = move(1); for (int i = 0; i < count; i++) { int code = currentReader.ReadInt32() & 0x7fffffff; if (isFirst) { if (player == 0) { currentWriter.Write(code); } else { currentWriter.Write(0); } } else { if (player == 0) { currentWriter.Write(0); } else { currentWriter.Write(code); } } } break; case GameMessage.PayLpCost: case GameMessage.LpUpdate: case GameMessage.Damage: case GameMessage.Recover: move(5); break; case GameMessage.Equip: move(8); break; case GameMessage.Unequip: move(4); break; case GameMessage.CardTarget: case GameMessage.CancelTarget: move(8); break; case GameMessage.AddCounter: case GameMessage.RemoveCounter: move(7); break; case GameMessage.Attack: move(8); break; case GameMessage.Battle: move(26); break; case GameMessage.AttackDiabled: break; case GameMessage.DamageStepStart: break; case GameMessage.DamageStepEnd: break; case GameMessage.MissedEffect: move(8); break; case GameMessage.BeChainTarget: break; case GameMessage.CreateRelation: break; case GameMessage.ReleaseRelation: break; case GameMessage.TossCoin: case GameMessage.TossDice: move(1); move(move(1)); break; case GameMessage.AnnounceRace: move(6); returnValue = true; break; case GameMessage.AnnounceAttrib: move(6); returnValue = true; break; case GameMessage.AnnounceCard: case GameMessage.AnnounceNumber: move(1); move(move(1) * 4); returnValue = true; break; case GameMessage.CardHint: move(9); break; case GameMessage.TagSwap: player = move(1); move(1); int ecount = move(1); move(1); int hcount = move(1); move(4); for (int i = 0; i < hcount + ecount; i++) { uint code = currentReader.ReadUInt32(); if ((code & 0x80000000) != 0) currentWriter.Write(code); else currentWriter.Write(0); } break; case GameMessage.ReloadField: move(1); for (int i_ = 0; i_ < 2; i_++) { move(4); for (int i = 0; i < 7; i++) { int val = move(1); if (val > 0) { move(2); } } for (int i = 0; i < 8; i++) { int val = move(1); if (val > 0) { move(1); } } move(1); move(1); move(1); move(1); move(1); move(1); move(move(1) * 15); } break; case GameMessage.AiName: var length = currentReader.ReadUInt16(); currentWriter.Write(length); move(length + 1); break; case GameMessage.ShowHint: var length2 = currentReader.ReadUInt16(); currentWriter.Write(length2); move(length2 + 1); break; case GameMessage.PlayerHint: move(6); break; case GameMessage.MatchKill: move(4); break; case GameMessage.CustomMsg: break; case GameMessage.DuelWinner: break; default: returnValue = true; break; } flush(); switch (mes) { case GameMessage.RefreshDeck: case GameMessage.SwapGraveDeck: case GameMessage.ShuffleSetCard: case GameMessage.ShuffleDeck: case GameMessage.ShuffleHand: case GameMessage.ReverseDeck: case GameMessage.DeckTop: case GameMessage.Summoned: case GameMessage.SpSummoned: case GameMessage.FlipSummoned: case GameMessage.ChainSolved: case GameMessage.ChainEnd: case GameMessage.ChainNegated: case GameMessage.ChainDisabled: case GameMessage.Battle: case GameMessage.DamageStepEnd: case GameMessage.TagSwap: case GameMessage.ReloadField: case GameMessage.Draw: case GameMessage.Set: Refresh(); break; } DebugLog(mes.ToString() + (returnValue ? (" Wating Buffer:\n"+BitConverter.ToString(((MemoryStream)(currentWriter.BaseStream)).ToArray())) : "")); return returnValue; } } public class YRP { public int ID = 0; public int Version = 0; public int Flag = 0; public uint Seed = 0; public uint[] SeedsV2 = new uint[8]; public long DataSize = 0; public int Hash = 0; public byte[] Props = new byte[8]; public int StartLp = 0; public int StartHand = 0; public int DrawCount = 0; public uint opt = 0; public class PlayerData { public string name; public List main = new List(); public List extra = new List(); } public List playerData = new List(); public List gameData = new List(); public byte[] getNamePacket() { MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); if (playerData.Count == 4) { WriteUnicode(writer, playerData[0].name, 50); WriteUnicode(writer, playerData[1].name, 50); WriteUnicode(writer, playerData[0].name, 50); WriteUnicode(writer, playerData[2].name, 50); WriteUnicode(writer, playerData[3].name, 50); WriteUnicode(writer, playerData[2].name, 50); } else { WriteUnicode(writer, playerData[0].name, 50); WriteUnicode(writer, playerData[0].name, 50); WriteUnicode(writer, playerData[0].name, 50); WriteUnicode(writer, playerData[1].name, 50); WriteUnicode(writer, playerData[1].name, 50); WriteUnicode(writer, playerData[1].name, 50); } writer.Write((Int32)(opt >> 16)); BinaryWriter Rwriter = new BinaryWriter(new MemoryStream()); Rwriter.Write((byte)YGOSharp.OCGWrapper.Enums.GameMessage.sibyl_name); Rwriter.Write(stream.ToArray()); return ((MemoryStream)(Rwriter.BaseStream)).ToArray(); } void WriteUnicode(BinaryWriter writer, string text, int len) { byte[] unicode = Encoding.Unicode.GetBytes(text); byte[] result = new byte[len * 2]; for (int i = 0; i < result.Length; i++) { result[i] = 204; } int max = len * 2 - 2; Array.Copy(unicode, result, unicode.Length > max ? max : unicode.Length); result[unicode.Length] = 0; result[unicode.Length + 1] = 0; writer.Write(result); } } }