Commit 1d25b276 authored by wind2009's avatar wind2009

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

parents bb85bb0c 7d0a5a85
...@@ -360,7 +360,7 @@ namespace WindBot.Game ...@@ -360,7 +360,7 @@ namespace WindBot.Game
/// <param name="forced">You can't return -1 if this param is true.</param> /// <param name="forced">You can't return -1 if this param is true.</param>
/// <param name="timing">Current hint timing</param> /// <param name="timing">Current hint timing</param>
/// <returns>Index of the activated card or -1.</returns> /// <returns>Index of the activated card or -1.</returns>
public int OnSelectChain(IList<ClientCard> cards, IList<int> descs, bool forced, int timing = -1) public int OnSelectChain(IList<ClientCard> cards, IList<int> descs, IList<bool> forces, int timing = -1)
{ {
Executor.OnSelectChain(cards); Executor.OnSelectChain(cards);
foreach (CardExecutor exec in Executor.Executors) foreach (CardExecutor exec in Executor.Executors)
...@@ -375,8 +375,17 @@ namespace WindBot.Game ...@@ -375,8 +375,17 @@ namespace WindBot.Game
} }
} }
} }
// If we're forced to chain, we chain the first card. However don't do anything. for (int i = 0; i < forces.Count; ++i)
return forced ? 0 : -1; {
if (forces[i])
{
// If the card is forced, we have to activate it.
_dialogs.SendChaining(cards[i].Name);
return i;
}
}
// Don't do anything.
return -1;
} }
/// <summary> /// <summary>
......
...@@ -298,6 +298,8 @@ namespace WindBot.Game ...@@ -298,6 +298,8 @@ namespace WindBot.Game
string otherName = (player == 0) ? _room.Names[1] : _room.Names[0]; string otherName = (player == 0) ? _room.Names[1] : _room.Names[0];
if (player < 4) if (player < 4)
Logger.DebugWriteLine(otherName + " say to " + myName + ": " + message); Logger.DebugWriteLine(otherName + " say to " + myName + ": " + message);
else
Logger.DebugWriteLine("System message(" + player + "): " + message);
} }
private void OnErrorMsg(BinaryReader packet) private void OnErrorMsg(BinaryReader packet)
...@@ -308,6 +310,7 @@ namespace WindBot.Game ...@@ -308,6 +310,7 @@ namespace WindBot.Game
packet.ReadByte(); packet.ReadByte();
packet.ReadByte(); packet.ReadByte();
int pcode = packet.ReadInt32(); int pcode = packet.ReadInt32();
Logger.DebugWriteLine("Error message received: " + msg + ", code: " + pcode);
if (msg == 2) //ERRMSG_DECKERROR if (msg == 2) //ERRMSG_DECKERROR
{ {
int code = pcode & 0xFFFFFFF; int code = pcode & 0xFFFFFFF;
...@@ -1169,16 +1172,19 @@ namespace WindBot.Game ...@@ -1169,16 +1172,19 @@ namespace WindBot.Game
packet.ReadByte(); // player packet.ReadByte(); // player
int count = packet.ReadByte(); int count = packet.ReadByte();
packet.ReadByte(); // specount packet.ReadByte(); // specount
bool forced = packet.ReadByte() != 0;
int hint1 = packet.ReadInt32(); // hint1 int hint1 = packet.ReadInt32(); // hint1
int hint2 = packet.ReadInt32(); // hint2 int hint2 = packet.ReadInt32(); // hint2
// TODO: use ChainInfo?
IList<ClientCard> cards = new List<ClientCard>(); IList<ClientCard> cards = new List<ClientCard>();
IList<int> descs = new List<int>(); IList<int> descs = new List<int>();
IList<bool> forces = new List<bool>();
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
packet.ReadByte(); // flag packet.ReadByte(); // flag
bool forced = packet.ReadByte() != 0;
int id = packet.ReadInt32(); int id = packet.ReadInt32();
int con = GetLocalPlayer(packet.ReadByte()); int con = GetLocalPlayer(packet.ReadByte());
int loc = packet.ReadByte(); int loc = packet.ReadByte();
...@@ -1197,6 +1203,7 @@ namespace WindBot.Game ...@@ -1197,6 +1203,7 @@ namespace WindBot.Game
cards.Add(card); cards.Add(card);
descs.Add(desc); descs.Add(desc);
forces.Add(forced);
} }
if (cards.Count == 0) if (cards.Count == 0)
...@@ -1205,13 +1212,13 @@ namespace WindBot.Game ...@@ -1205,13 +1212,13 @@ namespace WindBot.Game
return; return;
} }
if (cards.Count == 1 && forced) if (cards.Count == 1 && forces[0])
{ {
Connection.Send(CtosMessage.Response, 0); Connection.Send(CtosMessage.Response, 0);
return; return;
} }
Connection.Send(CtosMessage.Response, _ai.OnSelectChain(cards, descs, forced, hint1 | hint2)); Connection.Send(CtosMessage.Response, _ai.OnSelectChain(cards, descs, forces, hint1 | hint2));
} }
private void OnSelectCounter(BinaryReader packet) private void OnSelectCounter(BinaryReader packet)
...@@ -1595,6 +1602,11 @@ namespace WindBot.Game ...@@ -1595,6 +1602,11 @@ namespace WindBot.Game
int OpParam = packet.ReadInt32(); int OpParam = packet.ReadInt32();
int OpParam1 = OpParam & 0xffff; int OpParam1 = OpParam & 0xffff;
int OpParam2 = OpParam >> 16; int OpParam2 = OpParam >> 16;
if ((OpParam & 0x80000000) > 0)
{
OpParam1 = OpParam & 0x7fffffff;
OpParam2 = 0;
}
if (OpParam2 > 0 && OpParam1 > OpParam2) if (OpParam2 > 0 && OpParam1 > OpParam2)
{ {
card.OpParam1 = OpParam2; card.OpParam1 = OpParam2;
...@@ -1989,6 +2001,7 @@ namespace WindBot.Game ...@@ -1989,6 +2001,7 @@ namespace WindBot.Game
private void OnConfirmCards(BinaryReader packet) private void OnConfirmCards(BinaryReader packet)
{ {
/*int playerid = */packet.ReadByte(); /*int playerid = */packet.ReadByte();
/*int skip_panel = */packet.ReadByte();
int count = packet.ReadByte(); int count = packet.ReadByte();
for (int i = 0; i < count; ++ i) for (int i = 0; i < count; ++ i)
{ {
......
using System.IO; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text;
using YGOSharp.Network; using YGOSharp.Network;
using YGOSharp.Network.Enums; using YGOSharp.Network.Enums;
using YGOSharp.Network.Utils; using YGOSharp.Network.Utils;
...@@ -65,7 +65,12 @@ namespace WindBot.Game ...@@ -65,7 +65,12 @@ namespace WindBot.Game
private void OnConnected() private void OnConnected()
{ {
BinaryWriter packet = GamePacketFactory.Create(CtosMessage.PlayerInfo); BinaryWriter packet = GamePacketFactory.Create(CtosMessage.ExternalAddress);
packet.Write((UInt32)0); // real_ip, is always 0 in normal client
packet.WriteUnicodeAutoLength(_serverHost, 255);
Connection.Send(packet);
packet = GamePacketFactory.Create(CtosMessage.PlayerInfo);
packet.WriteUnicode(Username, 20); packet.WriteUnicode(Username, 20);
Connection.Send(packet); Connection.Send(packet);
...@@ -73,7 +78,7 @@ namespace WindBot.Game ...@@ -73,7 +78,7 @@ namespace WindBot.Game
packet = GamePacketFactory.Create(CtosMessage.JoinGame); packet = GamePacketFactory.Create(CtosMessage.JoinGame);
packet.Write(_proVersion); packet.Write(_proVersion);
packet.Write(junk); packet.Write(junk);
packet.WriteUnicode(_roomInfo, 30); packet.WriteUnicode(_roomInfo, 20);
Connection.Send(packet); Connection.Send(packet);
} }
...@@ -84,9 +89,8 @@ namespace WindBot.Game ...@@ -84,9 +89,8 @@ namespace WindBot.Game
public void Chat(string message) public void Chat(string message)
{ {
byte[] content = Encoding.Unicode.GetBytes(message + "\0");
BinaryWriter chat = GamePacketFactory.Create(CtosMessage.Chat); BinaryWriter chat = GamePacketFactory.Create(CtosMessage.Chat);
chat.Write(content); chat.WriteUnicodeAutoLength(message, 255);
Connection.Send(chat); Connection.Send(chat);
} }
......
...@@ -136,10 +136,13 @@ WindBot can run as a "server", provide a http interface to create bot. ...@@ -136,10 +136,13 @@ WindBot can run as a "server", provide a http interface to create bot.
* Nekroz * Nekroz
### AI Template Generator ### Template Generator
A Java program which generate executor code from deck, made by Levyaton. A tool which generates a WindBot deck code template from a YGOPro deck file.
https://github.com/Levyaton/WindbotTemplateGenerator
You can use it to create a new deck for WindBot quickly.
https://mercury233.me/windbot/gen.html
### Server mode ### Server mode
......
...@@ -24,7 +24,7 @@ namespace WindBot ...@@ -24,7 +24,7 @@ namespace WindBot
Host = "127.0.0.1"; Host = "127.0.0.1";
Port = 7911; Port = 7911;
HostInfo = ""; HostInfo = "";
Version = 0x1361; Version = 0x1362;
Hand = 0; Hand = 0;
Debug = false; Debug = false;
Chat = true; Chat = true;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
Surrender = 0x14, Surrender = 0x14,
TimeConfirm = 0x15, TimeConfirm = 0x15,
Chat = 0x16, Chat = 0x16,
ExternalAddress = 0x17,
HsToDuelist = 0x20, HsToDuelist = 0x20,
HsToObserver = 0x21, HsToObserver = 0x21,
HsReady = 0x22, HsReady = 0x22,
......
...@@ -6,15 +6,40 @@ namespace YGOSharp.Network.Utils ...@@ -6,15 +6,40 @@ namespace YGOSharp.Network.Utils
{ {
public static class BinaryExtensions public static class BinaryExtensions
{ {
// fixed length strings
public static void WriteUnicode(this BinaryWriter writer, string text, int len) public static void WriteUnicode(this BinaryWriter writer, string text, int len)
{ {
byte[] unicode = Encoding.Unicode.GetBytes(text); byte[] unicode = Encoding.Unicode.GetBytes(text);
byte[] result = new byte[len * 2]; byte[] result = new byte[len * 2];
int max = len * 2 - 2; int copy = unicode.Length;
Array.Copy(unicode, result, unicode.Length > max ? max : unicode.Length); if (unicode.Length > len * 2 - 2)
{
copy = len * 2 - 2;
#if DEBUG
throw new ArgumentException("String '" + text + "' is too long for fixed length " + len + ".");
#endif
}
Array.Copy(unicode, result, copy);
writer.Write(result); writer.Write(result);
} }
// variable length strings
public static void WriteUnicodeAutoLength(this BinaryWriter writer, string text, int maxlen)
{
byte[] result = Encoding.Unicode.GetBytes(text + "\0");
int len = result.Length / 2;
if (len > maxlen)
{
len = maxlen;
result[len * 2 - 2] = 0;
result[len * 2 - 1] = 0;
#if DEBUG
throw new ArgumentException("String '" + text + "' is too long for max length " + maxlen + ".");
#endif
}
writer.Write(result, 0, len * 2);
}
public static string ReadUnicode(this BinaryReader reader, int len) public static string ReadUnicode(this BinaryReader reader, int len)
{ {
byte[] unicode = reader.ReadBytes(len * 2); byte[] unicode = reader.ReadBytes(len * 2);
......
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