mirror of
https://github.com/mm201/pkmn-classic-framework.git
synced 2026-04-25 08:04:27 -05:00
Implemented battle video server on GenV. (to test)
This commit is contained in:
parent
2b2c967e11
commit
a8d8c60d7a
|
|
@ -98,6 +98,111 @@ namespace PkmnFoundations.GlobalTerminalService
|
|||
Console.WriteLine("Retrieved {0} dressup results.", results.Length);
|
||||
|
||||
} break;
|
||||
|
||||
case RequestTypes5.BattleVideoUpload:
|
||||
{
|
||||
if (data.Length != 0x1ae8)
|
||||
{
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
int sigLength = BitConverter.ToInt32(data, 0x19e4);
|
||||
if (sigLength > 0x100 || sigLength < 0x00)
|
||||
{
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
byte[] battlevidData = new byte[0x18a4];
|
||||
|
||||
Array.Copy(data, 0x140, battlevidData, 0, 0x18a4);
|
||||
BattleVideoRecord5 record = new BattleVideoRecord5(pid, 0, battlevidData);
|
||||
byte[] vldtSignature = new byte[sigLength];
|
||||
Array.Copy(data, 0x19e8, vldtSignature, 0, sigLength);
|
||||
// todo: validate signature.
|
||||
|
||||
long serial = DataAbstract.Instance.BattleVideoUpload5(record);
|
||||
|
||||
if (serial == 0)
|
||||
{
|
||||
Console.WriteLine("Uploaded battle video already in server.");
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
Console.WriteLine("Battle video uploaded successfully.");
|
||||
response.Write(new byte[] { 0x00, 0x00 }, 0, 2); // result code (0 for OK)
|
||||
response.Write(BitConverter.GetBytes(serial), 0, 8);
|
||||
|
||||
} break;
|
||||
case RequestTypes5.BattleVideoSearch:
|
||||
{
|
||||
if (data.Length != 0x15c)
|
||||
{
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
// todo: validate or log some of this?
|
||||
BattleVideoSearchTypes5 type = (BattleVideoSearchTypes5)BitConverter.ToUInt32(data, 0x140);
|
||||
ushort species = BitConverter.ToUInt16(data, 0x144);
|
||||
BattleVideoMetagames5 meta = (BattleVideoMetagames5)data[0x146];
|
||||
// Byte 148 contains a magic number related to the searched metagame.
|
||||
// I don't think there's any need to verify it here.
|
||||
byte country = data[0x14a];
|
||||
byte region = data[0x14b];
|
||||
|
||||
Console.Write("Searching for ");
|
||||
if (type != BattleVideoSearchTypes5.None)
|
||||
Console.Write("{0}, ", type);
|
||||
if (species != 0xffff)
|
||||
Console.Write("species {0}, ", species);
|
||||
Console.Write("{0}", meta);
|
||||
if (country != 0xff)
|
||||
Console.Write(", country {0}", country);
|
||||
if (region != 0xff)
|
||||
Console.Write(", region {0}", region);
|
||||
Console.WriteLine(".");
|
||||
|
||||
BattleVideoHeader5[] results = DataAbstract.Instance.BattleVideoSearch5(species, type, meta, country, region, 30);
|
||||
response.Write(new byte[] { 0x00, 0x00 }, 0, 2); // result code (0 for OK)
|
||||
response.Write(BitConverter.GetBytes(results.Length), 0, 4);
|
||||
|
||||
foreach (BattleVideoHeader5 result in results)
|
||||
{
|
||||
response.Write(BitConverter.GetBytes(result.PID), 0, 4);
|
||||
response.Write(BitConverter.GetBytes(result.SerialNumber), 0, 8);
|
||||
response.Write(result.Data, 0, 0xc4);
|
||||
}
|
||||
Console.WriteLine("Retrieved {0} battle video results.", results.Length);
|
||||
|
||||
} break;
|
||||
case RequestTypes5.BattleVideoWatch:
|
||||
{
|
||||
if (data.Length != 0x14c)
|
||||
{
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
long serial = BitConverter.ToInt64(data, 0x140);
|
||||
BattleVideoRecord5 record = DataAbstract.Instance.BattleVideoGet5(serial);
|
||||
if (record == null)
|
||||
{
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
Console.WriteLine("Requested battle video {0} was missing.", BattleVideoHeader4.FormatSerial(serial));
|
||||
break;
|
||||
}
|
||||
|
||||
response.Write(new byte[] { 0x00, 0x00 }, 0, 2); // result code (0 for OK)
|
||||
response.Write(BitConverter.GetBytes(record.PID), 0, 4);
|
||||
response.Write(BitConverter.GetBytes(record.SerialNumber), 0, 8);
|
||||
response.Write(record.Header.Data, 0, 0xc4);
|
||||
response.Write(record.Data, 0, 0x17e0);
|
||||
Console.WriteLine("Retrieved battle video {0}.", BattleVideoHeader4.FormatSerial(serial));
|
||||
|
||||
} break;
|
||||
|
||||
default:
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ namespace PkmnFoundations.Data
|
|||
public abstract long MusicalUpload5(MusicalRecord5 record);
|
||||
public abstract MusicalRecord5[] MusicalSearch5(ushort species, int count);
|
||||
|
||||
//public abstract long BattleVideoUpload5(BattleVideoRecord5 record);
|
||||
//public abstract BattleVideoHeader5[] BattleVideoSearch5(ushort species, BattleVideoMetagames5 metagame, byte country, byte region, int count);
|
||||
//public abstract BattleVideoRecord5 BattleVideoGet5(long serial);
|
||||
public abstract long BattleVideoUpload5(BattleVideoRecord5 record);
|
||||
public abstract BattleVideoHeader5[] BattleVideoSearch5(ushort species, BattleVideoSearchTypes5 type, BattleVideoMetagames5 metagame, byte country, byte region, int count);
|
||||
public abstract BattleVideoRecord5 BattleVideoGet5(long serial);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -895,7 +895,7 @@ namespace PkmnFoundations.Data
|
|||
new MySqlParameter("@key", key));
|
||||
|
||||
// todo: make a proc to insert both video and party.
|
||||
InsertBattleVideoParty(record.Header, (ulong)key, tran);
|
||||
InsertBattleVideoParty4(record.Header, (ulong)key, tran);
|
||||
|
||||
tran.Commit();
|
||||
return serial;
|
||||
|
|
@ -922,7 +922,7 @@ namespace PkmnFoundations.Data
|
|||
|
||||
if (rows == 0) return 0;
|
||||
|
||||
InsertBattleVideoParty(record.Header, key, tran);
|
||||
InsertBattleVideoParty4(record.Header, key, tran);
|
||||
|
||||
tran.Commit();
|
||||
return record.SerialNumber;
|
||||
|
|
@ -931,7 +931,7 @@ namespace PkmnFoundations.Data
|
|||
}
|
||||
}
|
||||
|
||||
private void InsertBattleVideoParty(BattleVideoHeader4 header, ulong key, MySqlTransaction tran)
|
||||
private void InsertBattleVideoParty4(BattleVideoHeader4 header, ulong key, MySqlTransaction tran)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand("INSERT INTO " +
|
||||
"TerminalBattleVideoPokemon4 (video_id, Slot, Species) VALUES " +
|
||||
|
|
@ -1164,6 +1164,208 @@ namespace PkmnFoundations.Data
|
|||
return new MusicalRecord5(reader.GetInt32(0), reader.GetInt64(1), data);
|
||||
}
|
||||
|
||||
public override long BattleVideoUpload5(BattleVideoRecord5 record)
|
||||
{
|
||||
if (record.Data.Length != 6112) throw new ArgumentException();
|
||||
if (record.Header.Data.Length != 196) throw new ArgumentException();
|
||||
|
||||
using (MySqlConnection db = CreateConnection())
|
||||
{
|
||||
db.Open();
|
||||
using (MySqlTransaction tran = db.BeginTransaction())
|
||||
{
|
||||
long exists = (long)tran.ExecuteScalar("SELECT EXISTS(SELECT * " +
|
||||
"FROM TerminalBattleVideos5 WHERE md5 = unhex(md5(CONCAT(@header, @data))) " +
|
||||
"AND Data = @data AND Header = @header)",
|
||||
new MySqlParameter("@header", record.Header.Data),
|
||||
new MySqlParameter("@data", record.Data));
|
||||
if (exists != 0) return 0;
|
||||
|
||||
if (record.SerialNumber == 0)
|
||||
{
|
||||
long key = (long)tran.ExecuteScalar("INSERT INTO TerminalBattleVideos5 " +
|
||||
"(pid, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " +
|
||||
"Metagame, Country, Region) " +
|
||||
"VALUES (@pid, @header, @data, unhex(md5(CONCAT(@header, @data))), " +
|
||||
"UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region); " +
|
||||
"SELECT LAST_INSERT_ID()",
|
||||
new MySqlParameter("@pid", record.PID),
|
||||
new MySqlParameter("@header", record.Header.Data),
|
||||
new MySqlParameter("@data", record.Data),
|
||||
new MySqlParameter("@trainer", record.Header.TrainerName),
|
||||
new MySqlParameter("@metagame", (byte)record.Header.Metagame),
|
||||
new MySqlParameter("@country", (byte)record.Header.Country),
|
||||
new MySqlParameter("@region", (byte)record.Header.Region)
|
||||
);
|
||||
long serial = BattleVideoHeader4.KeyToSerial((long)key);
|
||||
|
||||
tran.ExecuteNonQuery("UPDATE TerminalBattleVideos5 SET " +
|
||||
"SerialNumber = @serial WHERE id = @key",
|
||||
new MySqlParameter("@serial", serial),
|
||||
new MySqlParameter("@key", key));
|
||||
|
||||
// todo: make a proc to insert both video and party.
|
||||
InsertBattleVideoParty5(record.Header, (ulong)key, tran);
|
||||
|
||||
tran.Commit();
|
||||
return serial;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong key = (ulong)BattleVideoHeader4.SerialToKey(record.SerialNumber);
|
||||
|
||||
int rows = tran.ExecuteNonQuery("INSERT INTO TerminalBattleVideos5 " +
|
||||
"(id, pid, SerialNumber, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " +
|
||||
"Metagame, Country, Region) " +
|
||||
"VALUES (@key, @pid, @serial, @header, @data, unhex(md5(CONCAT(@header, @data))), " +
|
||||
"UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region)",
|
||||
new MySqlParameter("@key", key),
|
||||
new MySqlParameter("@pid", record.PID),
|
||||
new MySqlParameter("@serial", record.SerialNumber),
|
||||
new MySqlParameter("@header", record.Header.Data),
|
||||
new MySqlParameter("@data", record.Data),
|
||||
new MySqlParameter("@trainer", record.Header.TrainerName),
|
||||
new MySqlParameter("@metagame", (byte)record.Header.Metagame),
|
||||
new MySqlParameter("@country", (byte)record.Header.Country),
|
||||
new MySqlParameter("@region", (byte)record.Header.Region)
|
||||
);
|
||||
|
||||
if (rows == 0) return 0;
|
||||
|
||||
InsertBattleVideoParty5(record.Header, key, tran);
|
||||
|
||||
tran.Commit();
|
||||
return record.SerialNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertBattleVideoParty5(BattleVideoHeader5 header, ulong key, MySqlTransaction tran)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand("INSERT INTO " +
|
||||
"TerminalBattleVideoPokemon5 (video_id, Slot, Species) VALUES " +
|
||||
"(@key, @slot, @species)", tran.Connection, tran);
|
||||
cmd.Parameters.Add("@key", MySqlDbType.UInt64).Value = key;
|
||||
cmd.Parameters.Add("@slot", MySqlDbType.UByte);
|
||||
cmd.Parameters.Add("@species", MySqlDbType.UInt16);
|
||||
|
||||
ushort[] party = header.Party;
|
||||
for (byte x = 0; x < 12; x++)
|
||||
{
|
||||
ushort species = party[x];
|
||||
if (species == 0) continue;
|
||||
cmd.Parameters["@slot"].Value = x;
|
||||
cmd.Parameters["@species"].Value = species;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public override BattleVideoHeader5[] BattleVideoSearch5(ushort species, BattleVideoSearchTypes5 type, BattleVideoMetagames5 metagame, byte country, byte region, int count)
|
||||
{
|
||||
using (MySqlConnection db = CreateConnection())
|
||||
{
|
||||
List<MySqlParameter> _params = new List<MySqlParameter>();
|
||||
String where = "";
|
||||
bool hasSearch = false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case BattleVideoSearchTypes5.TopLinkBattles:
|
||||
break;
|
||||
case BattleVideoSearchTypes5.TopSubwayBattles:
|
||||
break;
|
||||
}
|
||||
|
||||
if (species != 0xffff)
|
||||
{
|
||||
where += (hasSearch ? " AND " : " WHERE ") +
|
||||
"EXISTS(SELECT * FROM TerminalBattleVideoPokemon5 " +
|
||||
"WHERE video_id = TerminalBattleVideos5.id AND Species = @species)";
|
||||
_params.Add(new MySqlParameter("@species", species));
|
||||
hasSearch = true;
|
||||
}
|
||||
|
||||
// todo: find out if there are ranged searches on GenV too.
|
||||
/*
|
||||
if (metagame == BattleVideoMetagames4.SearchColosseumSingleNoRestrictions)
|
||||
metagame = BattleVideoMetagames4.ColosseumSingleNoRestrictions;
|
||||
if (metagame == BattleVideoMetagames4.SearchColosseumDoubleNoRestrictions)
|
||||
metagame = BattleVideoMetagames4.ColosseumDoubleNoRestrictions;
|
||||
* */
|
||||
|
||||
if (metagame != BattleVideoMetagames5.None)
|
||||
{
|
||||
where += (hasSearch ? " AND " : " WHERE ") + "Metagame = @metagame";
|
||||
_params.Add(new MySqlParameter("@metagame", (byte)metagame));
|
||||
hasSearch = true;
|
||||
}
|
||||
|
||||
if (country != 0xff)
|
||||
{
|
||||
where += (hasSearch ? " AND " : " WHERE ") + "Country = @country";
|
||||
_params.Add(new MySqlParameter("@country", country));
|
||||
hasSearch = true;
|
||||
}
|
||||
|
||||
if (region != 0xff)
|
||||
{
|
||||
where += (hasSearch ? " AND " : " WHERE ") + "Region = @region";
|
||||
_params.Add(new MySqlParameter("@region", region));
|
||||
}
|
||||
|
||||
_params.Add(new MySqlParameter("@count", count));
|
||||
|
||||
db.Open();
|
||||
|
||||
List<BattleVideoHeader5> results = new List<BattleVideoHeader5>(count);
|
||||
MySqlDataReader reader = (MySqlDataReader)db.ExecuteReader("SELECT pid, " +
|
||||
"SerialNumber, Header FROM TerminalBattleVideos5" + where +
|
||||
" ORDER BY TimeAdded DESC LIMIT @count",
|
||||
_params.ToArray());
|
||||
while (reader.Read())
|
||||
{
|
||||
results.Add(BattleVideoHeader5FromReader(reader));
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
db.Close();
|
||||
return results.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private BattleVideoHeader5 BattleVideoHeader5FromReader(MySqlDataReader reader)
|
||||
{
|
||||
byte[] data = new byte[196];
|
||||
reader.GetBytes(2, 0, data, 0, 196);
|
||||
|
||||
return new BattleVideoHeader5(reader.GetInt32(0), reader.GetInt64(1), data);
|
||||
}
|
||||
|
||||
public override BattleVideoRecord5 BattleVideoGet5(long serial)
|
||||
{
|
||||
using (MySqlConnection db = CreateConnection())
|
||||
{
|
||||
db.Open();
|
||||
MySqlDataReader reader = (MySqlDataReader)db.ExecuteReader("SELECT pid, " +
|
||||
"SerialNumber, Header, Data FROM TerminalBattleVideos5 " +
|
||||
"WHERE SerialNumber = @serial",
|
||||
new MySqlParameter("@serial", serial));
|
||||
|
||||
if (reader.Read())
|
||||
return BattleVideo5FromReader(reader);
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
|
||||
private BattleVideoRecord5 BattleVideo5FromReader(MySqlDataReader reader)
|
||||
{
|
||||
byte[] data = new byte[6112];
|
||||
reader.GetBytes(3, 0, data, 0, 6112);
|
||||
BattleVideoHeader5 header = BattleVideoHeader5FromReader(reader);
|
||||
|
||||
return new BattleVideoRecord5(header.PID, header.SerialNumber, header, data);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,9 @@
|
|||
<Compile Include="Data\DataSqlite.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Structures\BattleVideoHeader4.cs" />
|
||||
<Compile Include="Structures\BattleVideoHeader5.cs" />
|
||||
<Compile Include="Structures\BattleVideoRecord4.cs" />
|
||||
<Compile Include="Structures\BattleVideoRecord5.cs" />
|
||||
<Compile Include="Structures\BoxRecord4.cs" />
|
||||
<Compile Include="Structures\DressupRecord4.cs" />
|
||||
<Compile Include="Structures\GtsRecord5.cs" />
|
||||
|
|
|
|||
116
library/Structures/BattleVideoHeader5.cs
Normal file
116
library/Structures/BattleVideoHeader5.cs
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class BattleVideoHeader5
|
||||
{
|
||||
public BattleVideoHeader5()
|
||||
{
|
||||
}
|
||||
|
||||
public BattleVideoHeader5(int pid, long serial_number, byte[] data)
|
||||
{
|
||||
if (data.Length != 196) throw new ArgumentException("Battle video header data must be 196 bytes.");
|
||||
|
||||
PID = pid;
|
||||
SerialNumber = serial_number;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
// todo: encapsulate these so calculated fields are always correct
|
||||
public int PID;
|
||||
public long SerialNumber;
|
||||
public byte[] Data;
|
||||
|
||||
public ushort[] Party
|
||||
{
|
||||
get
|
||||
{
|
||||
ushort[] result = new ushort[12];
|
||||
for (int x = 0; x < result.Length; x++)
|
||||
{
|
||||
result[x] = BitConverter.ToUInt16(Data, 0x80 + x * 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] TrainerName
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] result = new byte[16];
|
||||
Array.Copy(Data, 0, result, 0, 16);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public BattleVideoMetagames5 Metagame
|
||||
{
|
||||
get
|
||||
{
|
||||
return (BattleVideoMetagames5)Data[0xa6];
|
||||
}
|
||||
}
|
||||
|
||||
public byte Country
|
||||
{
|
||||
get
|
||||
{
|
||||
return Data[0x17];
|
||||
}
|
||||
}
|
||||
|
||||
public byte Region
|
||||
{
|
||||
get
|
||||
{
|
||||
return Data[0x18];
|
||||
}
|
||||
}
|
||||
|
||||
public BattleVideoHeader5 Clone()
|
||||
{
|
||||
return new BattleVideoHeader5(PID, SerialNumber, Data.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public enum BattleVideoMetagames5 : byte
|
||||
{
|
||||
None = 0x00,
|
||||
|
||||
ColosseumSingleNoLauncher = 0x18,
|
||||
ColosseumSingleLauncher = 0x98,
|
||||
ColosseumDoubleNoLauncher = 0x19,
|
||||
ColosseumDoubleLauncher = 0x99,
|
||||
ColosseumTripleNoLauncher = 0x1a,
|
||||
ColosseumTripleLauncher = 0x9a,
|
||||
ColosseumRotationNoLauncher = 0x1b,
|
||||
ColosseumRotationLauncher = 0x9b,
|
||||
ColosseumMultiNoLauncher = 0x1c,
|
||||
ColosseumMultiLauncher = 0x9c,
|
||||
|
||||
BattleSubwaySingle = 0x00,
|
||||
BattleSubwayDouble = 0x01,
|
||||
BattleSubwayMulti = 0x04,
|
||||
|
||||
RandomMatchupSingle = 0x28,
|
||||
RandomMatchupDouble = 0x29,
|
||||
RandomMatchupTriple = 0x2a,
|
||||
RandomMatchupRotation = 0x2b,
|
||||
RandomMatchupLauncher = 0xaa,
|
||||
|
||||
BattleCompetition = 0x38,
|
||||
}
|
||||
|
||||
public enum BattleVideoSearchTypes5 : uint
|
||||
{
|
||||
None = 0x00000000,
|
||||
Latest30 = 0x00000001,
|
||||
TopLinkBattles = 0x00000003,
|
||||
TopSubwayBattles = 0x00000002,
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ namespace PkmnFoundations.Structures
|
|||
|
||||
public BattleVideoRecord4(int pid, long serial_number, BattleVideoHeader4 header, byte[] data_main)
|
||||
{
|
||||
if (data_main.Length != 7272) throw new ArgumentException("Battle video main data must be 7500 bytes.");
|
||||
if (data_main.Length != 7272) throw new ArgumentException("Battle video main data must be 7272 bytes.");
|
||||
|
||||
PID = pid;
|
||||
SerialNumber = serial_number;
|
||||
|
|
|
|||
58
library/Structures/BattleVideoRecord5.cs
Normal file
58
library/Structures/BattleVideoRecord5.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class BattleVideoRecord5
|
||||
{
|
||||
public BattleVideoRecord5()
|
||||
{
|
||||
}
|
||||
|
||||
public BattleVideoRecord5(int pid, long serial_number, byte[] data)
|
||||
{
|
||||
if (data.Length != 6308) throw new ArgumentException("Battle video data must be 6308 bytes.");
|
||||
|
||||
byte[] data_head = new byte[196];
|
||||
byte[] data_main = new byte[6112];
|
||||
|
||||
Array.Copy(data, 0, data_head, 0, 196);
|
||||
Array.Copy(data, 196, data_main, 0, 6112);
|
||||
|
||||
PID = pid;
|
||||
SerialNumber = serial_number;
|
||||
Header = new BattleVideoHeader5(pid, serial_number, data_head);
|
||||
Data = data_main;
|
||||
}
|
||||
|
||||
public BattleVideoRecord5(int pid, long serial_number, BattleVideoHeader5 header, byte[] data_main)
|
||||
{
|
||||
if (data_main.Length != 6112) throw new ArgumentException("Battle video main data must be 6112 bytes.");
|
||||
|
||||
PID = pid;
|
||||
SerialNumber = serial_number;
|
||||
Header = header;
|
||||
Data = data_main;
|
||||
}
|
||||
|
||||
public int PID;
|
||||
public long SerialNumber;
|
||||
public BattleVideoHeader5 Header;
|
||||
public byte[] Data;
|
||||
|
||||
public BattleVideoRecord5 Clone()
|
||||
{
|
||||
return new BattleVideoRecord5(PID, SerialNumber, Header.Clone(), Data.ToArray());
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
{
|
||||
byte[] result = new byte[6308];
|
||||
Array.Copy(Header.Data, 0, result, 0, 196);
|
||||
Array.Copy(Data, 196, result, 0, 6112);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user