s/datagram/record

This commit is contained in:
Greg Edwards 2014-04-29 09:57:49 -04:00
parent 392f9952cd
commit fc76ffdcaf
7 changed files with 118 additions and 118 deletions

View File

@ -10,16 +10,16 @@
<form id="form1" runat="server">
<div>
<asp:Label AssociatedControlID="txtDatagram" Text="Paste datagram data here (hex):" runat="server" />
<asp:TextBox ID="txtDatagram" TextMode="MultiLine" runat="server" />
<asp:Label AssociatedControlID="txtRecord" Text="Paste record data here (hex):" runat="server" />
<asp:TextBox ID="txtRecord" TextMode="MultiLine" runat="server" />
<asp:Button ID="btnSend" OnClick="btnSend_Click" Text="Send" runat="server" />
<br />
<asp:Label AssociatedControlID="txtPid" Text="Enter your PID to retrieve raw datagram:" runat="server" />
<asp:Label AssociatedControlID="txtPid" Text="Enter your PID to retrieve raw record:" runat="server" />
<asp:TextBox ID="txtPid" runat="server" />
<asp:Button ID="btnReceive" OnClick="btnReceive_Click" Text="Receive" runat="server" />
<asp:Literal ID="litDatagram" runat="server" />
<asp:Literal ID="litRecord" runat="server" />
</div>
</form>

View File

@ -19,25 +19,25 @@ namespace PokeFoundations.GTS
protected void btnSend_Click(object sender, EventArgs e)
{
byte[] data = Common.FromHexString(txtDatagram.Text.Replace("\n", "").Replace("\r", "").Replace(" ", ""));
GtsDatagram4 datagram = new GtsDatagram4();
datagram.Load(data);
DataAbstract.Instance.GtsDepositPokemon4(datagram);
byte[] data = Common.FromHexString(txtRecord.Text.Replace("\n", "").Replace("\r", "").Replace(" ", ""));
GtsRecord4 record = new GtsRecord4();
record.Load(data);
DataAbstract.Instance.GtsDepositPokemon4(record);
}
protected void btnReceive_Click(object sender, EventArgs e)
{
int pid;
Int32.TryParse(txtPid.Text, out pid);
GtsDatagram4 datagram = DataAbstract.Instance.GtsDataForUser4(pid);
if (datagram == null)
GtsRecord4 record = DataAbstract.Instance.GtsDataForUser4(pid);
if (record == null)
{
litDatagram.Text = "No data for this PID";
litRecord.Text = "No data for this PID";
return;
}
byte[] data = datagram.Save();
litDatagram.Text = RenderHex(data.ToHexStringLower());
byte[] data = record.Save();
litRecord.Text = RenderHex(data.ToHexStringLower());
}

View File

@ -22,13 +22,13 @@ namespace PokeFoundations.GTS {
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
/// <summary>
/// txtDatagram control.
/// txtRecord control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtDatagram;
protected global::System.Web.UI.WebControls.TextBox txtRecord;
/// <summary>
/// btnSend control.
@ -58,12 +58,12 @@ namespace PokeFoundations.GTS {
protected global::System.Web.UI.WebControls.Button btnReceive;
/// <summary>
/// litDatagram control.
/// litRecord control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal litDatagram;
protected global::System.Web.UI.WebControls.Literal litRecord;
}
}

View File

@ -134,18 +134,18 @@ namespace PokeFoundations.GTS
* in the GTS, it responds with 0x0004; if not, it responds
* with 0x0005. */
GtsDatagram4 datagram = DataAbstract.Instance.GtsDataForUser4(pid);
GtsRecord4 record = DataAbstract.Instance.GtsDataForUser4(pid);
if (datagram == null)
if (record == null)
{
// No pokemon in the system
context.Response.OutputStream.Write(new byte[]
{ 0x05, 0x00 }, 0, 2);
}
else if (datagram.IsExchanged > 0)
else if (record.IsExchanged > 0)
{
// traded pokemon arriving!!!
context.Response.OutputStream.Write(datagram.Save(), 0, 292);
context.Response.OutputStream.Write(record.Save(), 0, 292);
}
else
{
@ -164,32 +164,32 @@ namespace PokeFoundations.GTS
// this is only called if result.asp returned 4.
// todo: what does this do if the contained pokemon is traded??
GtsDatagram4 datagram = DataAbstract.Instance.GtsDataForUser4(pid);
GtsRecord4 record = DataAbstract.Instance.GtsDataForUser4(pid);
if (datagram == null)
if (record == null)
{
// No pokemon in the system
// what do here?
}
else
{
// just write the datagram whether traded or not...
context.Response.OutputStream.Write(datagram.Save(), 0, 292);
// just write the record whether traded or not...
context.Response.OutputStream.Write(record.Save(), 0, 292);
}
} break;
// Called after result.asp returns an inbound pokemon datagram to delete it
// Called after result.asp returns an inbound pokemon record to delete it
case "/worldexchange/delete.asp":
{
sessions.Remove(session.Hash);
GtsDatagram4 datagram = DataAbstract.Instance.GtsDataForUser4(pid);
if (datagram == null)
GtsRecord4 record = DataAbstract.Instance.GtsDataForUser4(pid);
if (record == null)
{
context.Response.OutputStream.Write(new byte[]
{ 0x00, 0x00 }, 0, 2);
}
else if (datagram.IsExchanged > 0)
else if (record.IsExchanged > 0)
{
// delete the arrived pokemon from the system
// todo: add transactions
@ -217,13 +217,13 @@ namespace PokeFoundations.GTS
{
sessions.Remove(session.Hash);
GtsDatagram4 datagram = DataAbstract.Instance.GtsDataForUser4(pid);
if (datagram == null)
GtsRecord4 record = DataAbstract.Instance.GtsDataForUser4(pid);
if (record == null)
{
context.Response.OutputStream.Write(new byte[]
{ 0x00, 0x00 }, 0, 2);
}
else if (datagram.IsExchanged > 0)
else if (record.IsExchanged > 0)
{
// a traded pokemon is there, fail. Use delete.asp instead.
context.Response.OutputStream.Write(new byte[] { 0x00, 0x00 }, 0, 2);
@ -261,16 +261,16 @@ namespace PokeFoundations.GTS
break;
}
// keep the datagram in memory while we wait for post_finish.asp request
byte[] datagramBinary = new byte[292];
Array.Copy(data, 4, datagramBinary, 0, 292);
GtsDatagram4 datagram = new GtsDatagram4(datagramBinary);
// the following two fields are blank in the uploaded datagram.
// keep the record in memory while we wait for post_finish.asp request
byte[] recordBinary = new byte[292];
Array.Copy(data, 4, recordBinary, 0, 292);
GtsRecord4 record = new GtsRecord4(recordBinary);
// the following two fields are blank in the uploaded record.
// The server must provide them instead.
datagram.TimeDeposited = DateTime.Now;
datagram.PID = pid;
record.TimeDeposited = DateTime.Now;
record.PID = pid;
session.Tag = datagram;
session.Tag = record;
// todo: delete any other post.asp sessions registered under this PID
context.Response.OutputStream.Write(new byte[] { 0x01, 0x00 }, 0, 2);
@ -287,14 +287,14 @@ namespace PokeFoundations.GTS
return;
}
// find a matching session which contains our datagram
// find a matching session which contains our record
GtsSession4 prevSession = FindSession(sessions, pid, "/worldexchange/post.asp");
sessions.Remove(prevSession.Hash);
AssertHelper.Assert(prevSession.Tag is GtsDatagram4);
GtsDatagram4 datagram = (GtsDatagram4)prevSession.Tag;
AssertHelper.Assert(prevSession.Tag is GtsRecord4);
GtsRecord4 record = (GtsRecord4)prevSession.Tag;
if (DataAbstract.Instance.GtsDepositPokemon4(datagram))
if (DataAbstract.Instance.GtsDepositPokemon4(record))
context.Response.OutputStream.Write(new byte[] { 0x01, 0x00 }, 0, 2);
else
context.Response.OutputStream.Write(new byte[] { 0x00, 0x00 }, 0, 2);
@ -302,7 +302,7 @@ namespace PokeFoundations.GTS
} break;
// the search request has a funny bit string request of search terms
// and just returns a chunk of datagrams end to end.
// and just returns a chunk of records end to end.
case "/worldexchange/search.asp":
{
sessions.Remove(session.Hash);
@ -325,15 +325,15 @@ namespace PokeFoundations.GTS
if (data.Length > 11) country = data[11];
if (resultsCount > 7) resultsCount = 7; // stop DDOS
GtsDatagram4[] datagrams = DataAbstract.Instance.GtsSearch4(pid, species, gender, minLevel, maxLevel, country, resultsCount);
foreach (GtsDatagram4 datagram in datagrams)
GtsRecord4[] records = DataAbstract.Instance.GtsSearch4(pid, species, gender, minLevel, maxLevel, country, resultsCount);
foreach (GtsRecord4 record in records)
{
context.Response.OutputStream.Write(datagram.Save(), 0, 292);
context.Response.OutputStream.Write(record.Save(), 0, 292);
}
} break;
// the exchange request uploads a datagram of the exchangee pokemon
// the exchange request uploads a record of the exchangee pokemon
// plus the desired PID to trade for at the very end.
case "/worldexchange/exchange.asp":
{
@ -345,9 +345,9 @@ namespace PokeFoundations.GTS
byte[] uploadData = new byte[292];
Array.Copy(data, 4, uploadData, 0, 292);
GtsDatagram4 upload = new GtsDatagram4(uploadData);
GtsRecord4 upload = new GtsRecord4(uploadData);
int targetPid = BitConverter.ToInt32(data, 296);
GtsDatagram4 result = DataAbstract.Instance.GtsDataForUser4(targetPid);
GtsRecord4 result = DataAbstract.Instance.GtsDataForUser4(targetPid);
// enforce request requirements server side
if (!upload.CanTrade(result))
@ -362,7 +362,7 @@ namespace PokeFoundations.GTS
tag[1] = result;
session.Tag = tag;
GtsDatagram4 tradedResult = result.Clone();
GtsRecord4 tradedResult = result.Clone();
tradedResult.FlagTraded(upload); // only real purpose is to generate a proper response
context.Response.OutputStream.Write(result.Save(), 0, 292);
@ -379,18 +379,18 @@ namespace PokeFoundations.GTS
return;
}
// find a matching session which contains our datagram
// find a matching session which contains our record
GtsSession4 prevSession = FindSession(sessions, pid, "/worldexchange/exchange.asp");
sessions.Remove(prevSession.Hash);
AssertHelper.Assert(prevSession.Tag is object[]);
object[] tag = (object[])prevSession.Tag;
AssertHelper.Assert(tag.Length == 2);
AssertHelper.Assert(tag[0] is GtsDatagram4);
AssertHelper.Assert(tag[0] is GtsDatagram4);
AssertHelper.Assert(tag[0] is GtsRecord4);
AssertHelper.Assert(tag[0] is GtsRecord4);
GtsDatagram4 upload = (GtsDatagram4)tag[0];
GtsDatagram4 result = (GtsDatagram4)tag[1];
GtsRecord4 upload = (GtsRecord4)tag[0];
GtsRecord4 result = (GtsRecord4)tag[1];
if (DataAbstract.Instance.GtsTradePokemon4(upload, result))
context.Response.OutputStream.Write(new byte[] { 0x01, 0x00 }, 0, 2);

View File

@ -29,16 +29,16 @@ namespace PokeFoundations.Data
#endregion
#region GTS
public abstract GtsDatagram4 GtsDataForUser4(int pid);
public abstract GtsRecord4 GtsDataForUser4(int pid);
public abstract bool GtsDepositPokemon4(GtsDatagram4 datagram);
public abstract bool GtsDepositPokemon4(GtsRecord4 record);
public abstract bool GtsDeletePokemon4(int pid);
public abstract bool GtsTradePokemon4(int pidSrc, int pidDest);
public abstract bool GtsTradePokemon4(GtsDatagram4 upload, GtsDatagram4 result);
public abstract bool GtsTradePokemon4(GtsRecord4 upload, GtsRecord4 result);
public abstract GtsDatagram4[] GtsSearch4(int pid, ushort species, Genders gender, byte minLevel, byte maxLevel, byte country, int count);
public abstract GtsRecord4[] GtsSearch4(int pid, ushort species, Genders gender, byte minLevel, byte maxLevel, byte country, int count);
#endregion
}

View File

@ -35,7 +35,7 @@ namespace PokeFoundations.Data
#endregion
#region GTS
public GtsDatagram4 GtsDataForUser4(MySqlTransaction tran, int pid)
public GtsRecord4 GtsDataForUser4(MySqlTransaction tran, int pid)
{
MySqlDataReader reader = (MySqlDataReader)tran.ExecuteReader("SELECT Data, Species, Gender, Level, " +
"RequestedSpecies, RequestedGender, RequestedMinLevel, RequestedMaxLevel, " +
@ -49,7 +49,7 @@ namespace PokeFoundations.Data
reader.Close();
return null;
}
GtsDatagram4 result = Datagram4FromReader(reader);
GtsRecord4 result = Record4FromReader(reader);
#if DEBUG
AssertHelper.Equals(result.PID, pid);
#endif
@ -57,27 +57,27 @@ namespace PokeFoundations.Data
return result;
}
public override GtsDatagram4 GtsDataForUser4(int pid)
public override GtsRecord4 GtsDataForUser4(int pid)
{
using (MySqlConnection db = CreateConnection())
{
db.Open();
MySqlTransaction tran = db.BeginTransaction();
GtsDatagram4 result = GtsDataForUser4(tran, pid);
GtsRecord4 result = GtsDataForUser4(tran, pid);
tran.Commit();
return result;
}
}
public bool GtsDepositPokemon4(MySqlTransaction tran, GtsDatagram4 datagram)
public bool GtsDepositPokemon4(MySqlTransaction tran, GtsRecord4 record)
{
if (datagram.Data.Length != 236) throw new FormatException("pkm data must be 236 bytes.");
if (datagram.TrainerName.Length != 16) throw new FormatException("Trainer name must be 16 bytes.");
// note that IsTraded being true in the datagram is not an error condition
if (record.Data.Length != 236) throw new FormatException("pkm data must be 236 bytes.");
if (record.TrainerName.Length != 16) throw new FormatException("Trainer name must be 16 bytes.");
// note that IsTraded being true in the record is not an error condition
// since it might have use later on. You should check for this in the upload handler.
long count = (long)tran.ExecuteScalar("SELECT Count(*) FROM GtsPokemon4 WHERE pid = @pid",
new MySqlParameter("@pid", datagram.PID));
new MySqlParameter("@pid", record.PID));
if (count > 0)
{
@ -97,16 +97,16 @@ namespace PokeFoundations.Data
"@TrainerGender, @Unknown2, @TimeDeposited, @TimeWithdrawn, @pid, " +
"@TrainerName, @TrainerOT, @TrainerCountry, @TrainerRegion, @TrainerClass, " +
"@IsExchanged, @TrainerVersion, @TrainerLanguage)",
ParamsFromDatagram4(datagram));
ParamsFromRecord4(record));
return true;
}
public override bool GtsDepositPokemon4(GtsDatagram4 datagram)
public override bool GtsDepositPokemon4(GtsRecord4 record)
{
if (datagram.Data.Length != 236) throw new FormatException("pkm data must be 236 bytes.");
if (datagram.TrainerName.Length != 16) throw new FormatException("Trainer name must be 16 bytes.");
// note that IsTraded being true in the datagram is not an error condition
if (record.Data.Length != 236) throw new FormatException("pkm data must be 236 bytes.");
if (record.TrainerName.Length != 16) throw new FormatException("Trainer name must be 16 bytes.");
// note that IsTraded being true in the record is not an error condition
// since it might have use later on. You should check for this in the upload handler.
using (MySqlConnection db = CreateConnection())
@ -114,7 +114,7 @@ namespace PokeFoundations.Data
db.Open();
MySqlTransaction tran = db.BeginTransaction();
if (!GtsDepositPokemon4(tran, datagram))
if (!GtsDepositPokemon4(tran, record))
{
tran.Rollback();
return false;
@ -168,9 +168,9 @@ namespace PokeFoundations.Data
return false;
}
public override bool GtsTradePokemon4(GtsDatagram4 upload, GtsDatagram4 result)
public override bool GtsTradePokemon4(GtsRecord4 upload, GtsRecord4 result)
{
GtsDatagram4 traded = upload.Clone();
GtsRecord4 traded = upload.Clone();
traded.FlagTraded(result);
using (MySqlConnection db = CreateConnection())
@ -178,7 +178,7 @@ namespace PokeFoundations.Data
db.Open();
MySqlTransaction tran = db.BeginTransaction();
GtsDatagram4 resultOrig = GtsDataForUser4(tran, result.PID);
GtsRecord4 resultOrig = GtsDataForUser4(tran, result.PID);
if (resultOrig == null || resultOrig != result)
{
// looks like the pokemon was ninja'd between the Exchange and Exchange_finish
@ -203,7 +203,7 @@ namespace PokeFoundations.Data
}
}
public override GtsDatagram4[] GtsSearch4(int pid, ushort species, Genders gender, byte minLevel, byte maxLevel, byte country, int count)
public override GtsRecord4[] GtsSearch4(int pid, ushort species, Genders gender, byte minLevel, byte maxLevel, byte country, int count)
{
using (MySqlConnection db = CreateConnection())
{
@ -253,20 +253,20 @@ namespace PokeFoundations.Data
" ORDER BY TimeDeposited DESC LIMIT @count",
_params.ToArray());
List<GtsDatagram4> datagrams = new List<GtsDatagram4>(count);
List<GtsRecord4> records = new List<GtsRecord4>(count);
while (reader.Read())
{
datagrams.Add(Datagram4FromReader(reader));
records.Add(Record4FromReader(reader));
}
return datagrams.ToArray();
return records.ToArray();
}
}
private static GtsDatagram4 Datagram4FromReader(MySqlDataReader reader)
private static GtsRecord4 Record4FromReader(MySqlDataReader reader)
{
GtsDatagram4 result = new GtsDatagram4();
GtsRecord4 result = new GtsRecord4();
byte[] data = new byte[236];
reader.GetBytes(0, 0, data, 0, 236);
@ -305,32 +305,32 @@ namespace PokeFoundations.Data
return result;
}
private static MySqlParameter[] ParamsFromDatagram4(GtsDatagram4 datagram)
private static MySqlParameter[] ParamsFromRecord4(GtsRecord4 record)
{
MySqlParameter[] result = new MySqlParameter[22];
result[0] = new MySqlParameter("@Data", datagram.Data);
result[1] = new MySqlParameter("@Species", datagram.Species);
result[2] = new MySqlParameter("@Gender", (byte)datagram.Gender);
result[3] = new MySqlParameter("@Level", datagram.Level);
result[4] = new MySqlParameter("@RequestedSpecies", datagram.RequestedSpecies);
result[5] = new MySqlParameter("@RequestedGender", (byte)datagram.RequestedGender);
result[6] = new MySqlParameter("@RequestedMinLevel", datagram.RequestedMinLevel);
result[7] = new MySqlParameter("@RequestedMaxLevel", datagram.RequestedMaxLevel);
result[8] = new MySqlParameter("@Unknown1", datagram.Unknown1);
result[9] = new MySqlParameter("@TrainerGender", (byte)datagram.TrainerGender);
result[10] = new MySqlParameter("@Unknown2", datagram.Unknown2);
result[11] = new MySqlParameter("@TimeDeposited", datagram.TimeDeposited);
result[12] = new MySqlParameter("@TimeWithdrawn", datagram.TimeWithdrawn);
result[13] = new MySqlParameter("@pid", datagram.PID);
result[14] = new MySqlParameter("@TrainerName", datagram.TrainerName);
result[15] = new MySqlParameter("@TrainerOT", datagram.TrainerOT);
result[16] = new MySqlParameter("@TrainerCountry", datagram.TrainerCountry);
result[17] = new MySqlParameter("@TrainerRegion", datagram.TrainerRegion);
result[18] = new MySqlParameter("@TrainerClass", datagram.TrainerClass);
result[19] = new MySqlParameter("@IsExchanged", datagram.IsExchanged);
result[20] = new MySqlParameter("@TrainerVersion", datagram.TrainerVersion);
result[21] = new MySqlParameter("@TrainerLanguage", datagram.TrainerLanguage);
result[0] = new MySqlParameter("@Data", record.Data);
result[1] = new MySqlParameter("@Species", record.Species);
result[2] = new MySqlParameter("@Gender", (byte)record.Gender);
result[3] = new MySqlParameter("@Level", record.Level);
result[4] = new MySqlParameter("@RequestedSpecies", record.RequestedSpecies);
result[5] = new MySqlParameter("@RequestedGender", (byte)record.RequestedGender);
result[6] = new MySqlParameter("@RequestedMinLevel", record.RequestedMinLevel);
result[7] = new MySqlParameter("@RequestedMaxLevel", record.RequestedMaxLevel);
result[8] = new MySqlParameter("@Unknown1", record.Unknown1);
result[9] = new MySqlParameter("@TrainerGender", (byte)record.TrainerGender);
result[10] = new MySqlParameter("@Unknown2", record.Unknown2);
result[11] = new MySqlParameter("@TimeDeposited", record.TimeDeposited);
result[12] = new MySqlParameter("@TimeWithdrawn", record.TimeWithdrawn);
result[13] = new MySqlParameter("@pid", record.PID);
result[14] = new MySqlParameter("@TrainerName", record.TrainerName);
result[15] = new MySqlParameter("@TrainerOT", record.TrainerOT);
result[16] = new MySqlParameter("@TrainerCountry", record.TrainerCountry);
result[17] = new MySqlParameter("@TrainerRegion", record.TrainerRegion);
result[18] = new MySqlParameter("@TrainerClass", record.TrainerClass);
result[19] = new MySqlParameter("@IsExchanged", record.IsExchanged);
result[20] = new MySqlParameter("@TrainerVersion", record.TrainerVersion);
result[21] = new MySqlParameter("@TrainerLanguage", record.TrainerLanguage);
return result;
}

View File

@ -13,13 +13,13 @@ namespace PokeFoundations.Structures
/// and request.
/// </summary>
[Serializable()]
public class GtsDatagram4
public class GtsRecord4
{
public GtsDatagram4()
public GtsRecord4()
{
}
public GtsDatagram4(byte[] data)
public GtsRecord4(byte[] data)
{
Load(data);
}
@ -116,7 +116,7 @@ namespace PokeFoundations.Structures
public void Load(byte[] data)
{
if (data.Length != 292) throw new FormatException("GTS datagram length is incorrect.");
if (data.Length != 292) throw new FormatException("GTS record length is incorrect.");
Data = new byte[0xEC];
Array.Copy(data, 0, Data, 0, 0xEC);
@ -144,13 +144,13 @@ namespace PokeFoundations.Structures
TrainerLanguage = data[0x123];
}
public GtsDatagram4 Clone()
public GtsRecord4 Clone()
{
// todo: I am not very efficient
return new GtsDatagram4(Save());
return new GtsRecord4(Save());
}
public bool CanTrade(GtsDatagram4 other)
public bool CanTrade(GtsRecord4 other)
{
if (Species != other.RequestedSpecies) return false;
if (other.RequestedGender != Genders.Either && Gender != other.RequestedGender) return false;
@ -163,7 +163,7 @@ namespace PokeFoundations.Structures
return true;
}
public void FlagTraded(GtsDatagram4 other)
public void FlagTraded(GtsRecord4 other)
{
Species = other.Species;
Gender = other.Gender;
@ -213,7 +213,7 @@ namespace PokeFoundations.Structures
| (ulong)(date2.Second & 0xff) << 0x08;
}
public static bool operator ==(GtsDatagram4 a, GtsDatagram4 b)
public static bool operator ==(GtsRecord4 a, GtsRecord4 b)
{
if ((object)a == null && (object)b == null) return true;
if ((object)a == null || (object)b == null) return false;
@ -221,7 +221,7 @@ namespace PokeFoundations.Structures
return a.Save().SequenceEqual(b.Save());
}
public static bool operator !=(GtsDatagram4 a, GtsDatagram4 b)
public static bool operator !=(GtsRecord4 a, GtsRecord4 b)
{
return !(a == b);
}