WARFORGE

Здравствуйте, гость ( Авторизация | Регистрация )

Форумы работают на сервере
 Правила форума ЛОКАЛЬНЫЕ ПРАВИЛА ТЕХНИЧЕСКОГО ФОРУМА
 
Ответить на темуЗапустить новую тему
файл реплея .rec, структура, ошибки синхронизации и прочее
USSRxAZ
сообщение 12.04.2011, 18:40
Сообщение #1


Blackened
Maniac!
************

WH40k: Dawn of War II
Раса: Eldar
Армия: Farseer
Группа: Администратор
Сообщений: 3 366
Регистрация: 02.11.2006
Из: Новороссийск
Пользователь №: 6 400



Репутация:   1309  


Итак, переношу сюда дискуссию связанную с особенностями записи игр в файлы повтора .rec

Основная информация представлена в этой теме на официальном форуме игры

"формат файла 2005"

DATASDSC // START OF NEW CHUNK
2 // Chunk version (?)
95 // Chunk data size
0 // A variable string length
2 // (?)
2 // Number of teams (?)
6 // Number of players (?)
513 // Map Size
4 // String length
W40k // Game/engine name
7 // Double-byte string length
$.1.0.0.1.5.0. // Double-byte engine version string (?)
33 // A variable string length
DATA:Scenarios\MP\6P_KASYR_LUTIEN // Map name
4269834555 // Could this be the duration/time (?)
0 // (?)
0 // (?)
0 // (?)
DATABASE // START OF NEW CHUNK
4 // Chunk version (?)
125 // Chunk data size
0 // A variable string length
3 // (?)
8 // (?)
3853256620 // (?)
8 // (?)
1 // AIDF value
FDIA //= AIDF (AI Difficulty) - It took me a while to figure these out...backwards-endian smile.gif
0 // RSST value
TSSR //= RSST (Starting Resources)
0 // LKTM value
MTKL //= LKTM (Lock Teams)
1 // CHEA value
AEHC //= CHEA (Cheats Enabled)
0 // SLOC value
COLS //= SLOC (Starting Location)
2 // GSPD value
DPSG //= GSPD (Game Speed)
0 // RSSH value
HSSR //= RSSH (Resource Sharing)
1 // RSRT value
TRSR //= RSRT (Resource Rate)
0 // NOTE THIS IS A SINGLE ZERO BYTE (NOT A DWORD)
14 // Double-byte string length
3.v.3. .C.a.b.l.e. .O.n.l.y. // Double-byte game name
0 // (?)
1 // This is the number of Win conditions that are set. Each one is a constant DWORD that follows.
4137259138 // Win Condition - Annihilate
FOLDGPLY // START OF NEW CHUNK - GPLY = Game Player? There is one of these chunks for each player.
2 // Chunk version (?)
41330 // Chunk data size
0 // A variable string length
DATAINFO // START OF NEW CHUNK
1 // Chunk version (?)
54 // Chunk data size
0 // A variable string length
12 // Double-byte string length
B.e.e.z.e.r._.S.m.u.r.f. // Double-byte player name
2 // (?)
0 // (?)
10 // A string length
eldar_race // Race name
0 // (?)
FOLDTCUC // START OF NEW CHUNK - TCUC = Team Colors, something, something?
1 // Chunk version (?)
84 // Chunk data size
0 // A variable string length
DATALCIN // START OF NEW CHUNK - LCIN = Local?? NOTE: This section differs for the replay's "local" player
1 // Chunk version (?)
12 // Chunk data size
0 // A variable string length
0 // (?)
0 // (?)
0 // (?)
DATAUNCU // START OF NEW CHUNK - UNCU = ????
1 // Chunk version (?)
32 // Chunk data size
0 // A variable string length
4 // Double-byte string length
T.e.s.t. // Double-byte scheme name
FF FF FF FF // Primary NOTE: Colors are BGRA (blue, green, red, alpha)
FF FF FF FF // Secondary
FF FF FF FF // Trim
FF FF FF FF // Weapons
FF FF FF FF // Eyes
FOLDTCBD // START OF NEW CHUNK - TCBD = Team color Badge?
1 // Chunk version (?)
16460 // Chunk data size - A bigish chunk...hence the transferring badges lag smile.gif
0 // A variable string length
FOLDIMAG // START OF NEW CHUNK - IMAG = Image (badge in this case)
1 // Chunk version (?)
16440 // Chunk data size
0 // A variable string length
DATAATTR // START OF NEW CHUNK - ATTR = Image attribute(s)?
2 // Chunk version (?)
16 // Chunk data size
0 // A variable string length
0 // (?)
64 // Image WIDTH
64 // Image HEIGHT
1 // (?)
DATADATA // START OF NEW CHUNK - DATA = Image data?
2 // Chunk version (?)
1024 // Chunk data size
0 // A variable string length
<image data> // The image color values
FOLDTCBN // START OF NEW CHUNK - TCBN = Team color Banner?
1 // Chunk version (?)
24652 // Chunk data size
0 // A variable string length
FOLDIMAG // START OF NEW CHUNK - IMAG = Image (banner in this case)
1 // Chunk version (?)
1152 // Chunk data size
0 // A variable string length
DATAATTR // START OF NEW CHUNK - ATTR = Image attribute(s)?
2 // Chunk version (?)
16 // Chunk data size
0 // A variable string length
0 // (?)
64 // Image WIDTH
96 // Image HEIGHT
1 // (?)
DATADATA // START OF NEW CHUNK - DATA = Image data?
2 // Chunk version (?)
1536 // Chunk data size
<image data> // The image color values
FOLDGPLY...


"формат файла 2006"

@Pos: 0
[DWORD] // Replay Version 1 < Patch 1.3 with Patch 1.3 it got 2 after Patch 1.4 it goes to 4

[TEXT]->20Byte File Type "W40K_RECRelic Chunky"
[DWORD] // ???
[DWORD] // ???
[DWORD] // ???
[KEYWORD](FOLDPOST) // START OF NEW CHUNK
[DWORD] // Chunk version
[DWORD] // ???
[DWORD] // ???
[DWORD] // ???
[BYTE] // ???
[KEYWORD](DATADATA) // START OF NEW CHUNK
[DWORD] // Chunk version
[DWORD] // ???
[DWORD] // ???
[DWORD] // Total game duration
[TEXT]->12Byte // Relic Chunky
[DWORD] // Chunk version
[DWORD] // ???
[DWORD] // ???
[KEYWORD](FOLDINFO) // START OF NEW CHUNK
[DWORD] // Chunk version
[DWORD] // 4 byte info ?
[DWORD] // ???
[TEXT]->8Byte // GameInfo
[BYTE] // ???
[KEYWORD](FOLDWAN) // START OF NEW CHUNK
[DWORD] // Chunk version
[DWORD] // ???
[DWORD] // ???
[KEYWORD](DATASDSC) // START OF NEW CHUNK
[DWORD] // Chunk version (?) always 1 so far 2 for Version 4
[DWORD] // Chunk data size
[DWORD] // A variable string length
[DWORD] // (?)
[DWORD] // Number of teams (?)
[DWORD] // Number of active players (without spectators)
[DWORD] // Map Size
[DWORD] // String length
[DWORD] // Game/engine name
[DWORD]->%length% // length of additional header infos
[UNICODETEXT] // Double-byte engine version string (%length%*2)
[DWORD]->%length% // lenth of map Name
[TEXT] // Map name (%length%)
[DWORD] // (?)
[DWORD] // (?)
[DWORD] // (?)
[DWORD] // (?)

{REP VERSION 1}
[DWORD] // (?)
[BYTE] // (?)
[KEYWORD](FOLDMODI) // START OF NEW CHUNK
[DWORD] // Chunk version (?) always 1 so far
[DWORD] // (?)
[DWORD] // (?)
[KEYWORD](DATADMOD) // START OF NEW CHUNK
[DWORD] // Chunk version (?) always 4 so far
[DWORD]->%length% // Chunk data size
[TEXT] // (?) (%length%)
[KEYWORD](DATABASE) // START OF NEW CHUNK
[DWORD] // Chunk version (?) always 4 so far
[DWORD] // Chunk data size
{END VERSION 1}

{REP VERSION 2 OR 4}
[KEYWORD](DATABASE) // START OF NEW CHUNK
[DWORD] // Chunk version (?) always 4 so far
[DWORD] // Chunk data size
{END VERSION 2}

[DWORD] // Always 0 so far
[DWORD] // Always 3 so far
[DWORD] // Avavible Slots (after Patch 1.3 always 8 cause spec slots)
[DWORD] // (?)
[DWORD] // Always 8 so far
[DWORD] // (?)

{8 Keytext with 1byte value - not sorted!}
[DWORD] FDIA //= AIDF (AI Difficulty) - It took me a while to figure these out...backwards-endian
[DWORD] // 1. Byte is the value
[DWORD] TSSR //= RSST (Starting Resources)
[DWORD] // 1. Byte is the value
[DWORD] MTKL //= LKTM (Lock Teams)
[DWORD] // 1. Byte is the value
[DWORD] AEHC //= CHEA (Cheats Enabled)
[DWORD] // 1. Byte is the value
[DWORD] COLS //= SLOC (Starting Location)
[DWORD] // 1. Byte is the value
[DWORD] DPSG //= GSPD (Game Speed)
[DWORD] // 1. Byte is the value
[DWORD] HSSR //= RSSH (Resource Sharing)
[DWORD] // 1. Byte is the value
[DWORD] TRSR //= RSRT (Resource Rate)
[BYTE] // The Byte is the value

[DWORD]->%length% // length of ingame Name
[UNICODETEXT] // Double-byte game name (%length% * 2)
[DWORD] // End of Gamename Always 0 so far
[DWORD]->%length% // This is the number of Win conditions that are set. Each one is a constant DWORD that follows.

{%length% win conditions}
[DWORD] // Win conditon
-157708158 Annihilate
-1826760460 SuddenDeath
-1158102879 Assassinate
-779857721 EconomicVictory
735076042 ControlArea
863969525 DestroyHQ
1959084950 TakeandHolde
{END Win Conditions}

{Now for any Slot There come Player data}
[KEYWORD](FOLDGPLY) // START OF NEW CHUNK - GPLY = Game Player? There is one of these chunks for each player.
[DWORD] 2 // Chunk version (?) Always 2 so far
[DWORD] 41330 // Chunk data size
[DWORD] 0 // A variable string length Always 0 so far
[KEYWORD](DATAINFO) // START OF NEW CHUNK
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 54 // Chunk data size
[DWORD] 0 // A variable string length Always 0 so far
[DWORD]->%length% // length of Plyer Name
[UNICODETEXT] // Double-byte player name (%length% * 2)
[DWORD] // Type of Slot (0 Host/2 player/4 specc/7 empty/11 computer)
[DWORD] // Team of the Player (counter starts with 0)
[DWORD]->%length% // lengt of race string
[TEXT] // Race Name (%length%)
[DWORD] // (?) Always 0 so far

{REP VERSION 4}
//[DWORD]->%length% // (?) Always 0 so far
//[TEXT] // ? (%length%)

//After Version 1.5 there was this new Flag.
//[BYTE] ??? //It is only present in Version > 1.5
{END VERSION 4}

[KEYWORD](FOLDTCUC) // START OF NEW CHUNK - TCUC = Team Colors, something, something?
{Also Possible: FOLDGPLY -> New Player beginns (happens with spec slots)}

[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 84 // Chunk data size
[DWORD] 0 // A variable string length Always 0 so far
[KEYWORD](DATALCIN) // START OF NEW CHUNK - LCIN = Local?? NOTE: This section differs for the replay's "local" player
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD]->%length% 12 // Chunk data size
[TEXT] // (?) (%length%)
[DWORD] // (?) Always 0 so far
[KEYWORD](DATAUNCU) // START OF NEW CHUNK - UNCU = ????
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 32 // Chunk data size
[DWORD] 0 // A variable string length Always 0 so far
[DWORD]->%length% // length of ColorScheme
[UNICODETEXT] // Double-byte scheme name (%length% * 2)
[DWORD] // Primary NOTE: Colors are BGRA (blue, green, red, alpha)
[DWORD] // Secondary
[DWORD] // Trim
[DWORD] // Weapons
[DWORD] // Eyes

[KEYWORD](FOLDTCBD) // START OF NEW CHUNK - TCBD = Team color Badge?
{Also Possible: FOLDGPLY -> New Player beginns (happens sometimes...)}
{Another keyword FOLDTCBD -> Badge/Banner sometimes change their position in the Replay}
{If none of this Keywords is matchetd it seams like an broken header.. So ignore the 8byte keyword and go on with action data}

[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 16460 // Chunk data size - A bigish chunk...hence the transferring badges lag
[DWORD] 0 // A variable string length
[KEYWORD](FOLDIMAG) // START OF NEW CHUNK - IMAG = Image (badge in this case)
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 16460 // Chunk data size
[DWORD]->%length% // A variable string length
{IF %length% GT 0 then the Badge has a special Name}
[TEXT] // Name of the Badge (%length%)
{END}
[KEYWORD](DATAATTR) // START OF NEW CHUNK - ATTR = Image attribute(s)?
[DWORD] 2 // Chunk version (?) Always 2 so far
[DWORD] 16 // Chunk data size
[DWORD] 0 // (?)
[DWORD] 0 // (?)
[DWORD] 64 // Image WIDTH
[DWORD] 64 ´ // Image HEIGHT
[DWORD] 1 // (?) Always 1 so far
[KEYWORD](DATADATA) // START OF NEW CHUNK - DATA = Image data?
[DWORD] 2 // Chunk version (?) Always 2 so far
[DWORD] 16 // Chunk data size
[DWORD] 0 // (?)

{Now comes the image data. Pixel by pixel form heigth to width in RGBA colors - you also have to mirror the picture}


[KEYWORD](FOLDTCBN) // START OF NEW CHUNK - TCBN = Team color Banner?
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 24652 // Chunk data size
[DWORD] 0 // (?)
[KEYWORD](FOLDIMAG ) // START OF NEW CHUNK - IMAG = Image (banner in this case)
[DWORD] 1 // Chunk version (?) Always 1 so far
[DWORD] 1152 // Chunk data size
[DWORD] 0 // (?)
[KEYWORD](DATAATTR) // START OF NEW CHUNK - ATTR = Image attribute(s)?
[DWORD] 2 // Chunk version (?) Always 2 so far
[DWORD] 16 // Chunk data size
[DWORD] 0 // (?)
[DWORD] 0 // (?)
[DWORD] 64 // Image WIDTH
[DWORD] 96 ´ // Image HEIGHT
[DWORD] 1 // (?) Always 1 so far
[KEYWORD](DATADATA) // START OF NEW CHUNK - DATA = Image data?
[DWORD] 2 // Chunk version (?) Always 2 so far
[DWORD] 1536 // Chunk data size
[DWORD] 0 // (?)

{Now comes the image data. Pixel by pixel form heigth to width in RGBA colors - you also have to turn the picture}

{End of Player Data}

{Now The acion Data starts.. DoW is working with 8Ticks per second}
[DWORD] // Action 1 Key - Action Key 1 identefies an Chat msg so far
[DWORD] // Action 1 Length
{IF second action key is 1}
[DWORD] // Action 2 Key
{IF this action key is also 1 its an chat msg}
[DWORD] // Action 2 Length of Chat chunk
[BYTE] // Also length of Chat chunk so far
{IF REP Version 1}
[BYTE] // Player ID (As same orders as they are listed bevore)
[BYTE] // Reciver 0 All/1 Team/2 System
[BYTE] // (?)
{IF Rep Version 2 OR 4}
[DWORD]->%len% // Length of Player Name
[UNICODETEXT] // Double-byte player name (%len% * 2)
[DWORD] // Player ID > 1000 are normal players blow the IDs of the Spectators
[DWORD] // Msg Type 0 Player/1 Spec/2 System
[DWORD] // Reciver 0 All/1 Team/2 System
{End of Version spec Data}
[DWORD]->%len% // Length of Chat MSG
[UNICODETEXT] // Double-byte chat msg (%len% * 2)
{If second Action Key is not 1}
[DWORD]->%length% // length of action
[BYTE] // (?)
[TEXT] // (?) (%length%)
{If action key is 0}
[BYTE]
{IF REP version 2}
[BYTE] // Indicatios if the action block has action (1) or not (0)
{END Version depanding handling}
[DWORD] // Number of this tick (8 per second!)


"исходник менеджера реплеев на C#"

/*
* Created by SharpDevelop.
* User: Norbert 'GoWa' Laenger
* Date: 23.02.2006
* Time: 13:04
*/
// DoW/DoW:WA Replay Reader. Analyse and Show informatios from replay files.
// Copyright © Norbert 'GoWa' Laenger name of author
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

using System;
using System.IO;
using System.Collections;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace DoWRepReader
{
/// <summary>
/// Description of Class1.
/// </summary>
// Methods
public class RepReader
{
#region Variable deklaration
public Replay Replay;

private UnicodeEncoding encoding1;
private int counter;
private byte[] buffer;
private int num;
private char[] chr;
private string str;
private byte wincondvalue;
private int LastTick;

private ChatMessage Chat;
private Player Player;

private Analyse Cache;

private BinaryReader BinReader;
private BinaryWriter BinWriter;
#endregion

#region Events
// Events
public event EventHandler ReplayChanged;
#endregion

#region RepReader
public RepReader()
{
this.Chat = new ChatMessage();
this.Player = new Player();
this.encoding1 = new UnicodeEncoding();
}
#endregion
#region TickToTime
public static string TickToTime(int Tick)
{
Tick = Tick / 8;
int sec = Tick % 60;
int min = (Tick - sec) / 60;
return (min.ToString("D2") + ":" + sec.ToString("D2"));
}
#endregion
#region RenameIngame
public bool RenameIngame(string FileName, string name)
{
if(this.Replay.NameStart > 0)
{
if(this.OpenFile(FileName))
{
if(this.WriteFile(FileName + "rename.rec"))
{
this.BinReader.BaseStream.Position = 0;
this.BinWriter.BaseStream.Position = 0;
while(this.BinWriter.BaseStream.Position < this.Replay.BeginFOLDINFO)
{
this.BinWriter.Write(this.BinReader.ReadByte());
}
this.BinReader.BaseStream.Position = this.BinReader.BaseStream.Position + 4;
int len = this.Replay.LengthFOLDINFO - (this.Replay.Name.Length * 2) + (name.Length * 2);
this.BinWriter.Write(len);

while(this.BinWriter.BaseStream.Position < this.Replay.BeginDATABASE)
{
this.BinWriter.Write(this.BinReader.ReadByte());
}
//this.BinWriter.BaseStream.Position = this.Replay.BeginDATABASE;
this.BinReader.BaseStream.Position = this.BinReader.BaseStream.Position + 4;
len = this.Replay.LengthDATABASE - (this.Replay.Name.Length * 2) + (name.Length * 2);
this.BinWriter.Write(len);

while(this.BinWriter.BaseStream.Position < this.Replay.NameStart)
{
this.BinWriter.Write(this.BinReader.ReadByte());
}
//this.BinWriter.BaseStream.Position = this.Replay.NameStart;
this.BinReader.BaseStream.Position = this.BinReader.BaseStream.Position + 4;
len = name.Length;
this.BinWriter.Write(len);

for(int i=0; i < name.Length; i++)
{
Int16 ka = (Int16) name[i];
this.BinWriter.Write(ka);
}

this.BinReader.BaseStream.Position = this.BinReader.BaseStream.Position + (this.Replay.Name.Length * 2);
while (BinReader.BaseStream.Position < BinReader.BaseStream.Length)
{
this.BinWriter.Write(this.BinReader.ReadByte());

}
this.BinReader.Close();
this.BinWriter.Close();
File.Delete(FileName);
File.Move(FileName + "rename.rec", FileName);
return true;
}
else
{
this.BinReader.Close();
this.BinWriter.Close();
return false;
}
}
else
{
this.BinReader.Close();
this.BinWriter.Close();
return false;
}
}
else {
this.BinReader.Close();
this.BinWriter.Close();
return false;
}
}
#endregion
#region OpenFile
private bool OpenFile(string FileName)
{
try
{
Stream ReplayFile = File.OpenRead(FileName);

this.BinReader = new BinaryReader(ReplayFile, Encoding.ASCII);
return true;
}
catch (Exception)
{
this.BinReader.Close();
return false;
}
}
#endregion
#region WriteFile
private bool WriteFile(string FileName)
{
try
{
Stream ReplayFile = File.OpenWrite(FileName);

this.BinWriter = new BinaryWriter(ReplayFile, Encoding.ASCII);
return true;
}
catch (Exception)
{
this.BinWriter.Close();
return false;
}
}
#endregion
#region ReadHeaderOnly
public bool ReadHeaderOnly(string FileName)
{
bool ret = this.ReadHeader(FileName);
BinReader.Close();
return ret;
}
#endregion
#region ReadHeader
public bool ReadHeader(string FileName)
{
this.Replay = new Replay();

//MessageBox.Show("Header Start...");
if(this.OpenFile(FileName))
{
this.Replay.FileName = FileName;
//@Pos: 0
//[DWORD] // Replay Version 1 < Patch 1.3 with Patch 1.3 it got 2 after Patch 1.4 it goes to 4
this.Replay.Version = BinReader.ReadInt32();
//[TEXT]->20Byte File Type "W40K_RECRelic Chunky"
BinReader.ReadChars(20);
//[DWORD] // ???
BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[KEYWORD](FOLDPOST) // START OF NEW CHUNK
BinReader.ReadChars(8); // FOLDPOST
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // ???
BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadChars(12); // PostGameInfo
//[BYTE] // ???
BinReader.ReadByte();
//[KEYWORD](DATADATA) // START OF NEW CHUNK
BinReader.ReadChars(8); // DATADATA
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // ???
BinReader.ReadInt32(); // 4
//[DWORD] // ???
BinReader.ReadInt32(); // 0
//[DWORD] // Total game duration
int TotalTicks = BinReader.ReadInt32();
this.Replay.Duration = TickToTime(TotalTicks);
//[TEXT]->12Byte
BinReader.ReadChars(12); // Relic Chunky
//[DWORD] // ???
BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[KEYWORD](FOLDINFO) // START OF NEW CHUNK
BinReader.ReadChars(8); // FOLDINFO
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // 4 byte info ?
this.Replay.BeginFOLDINFO = this.BinReader.BaseStream.Position;
this.Replay.LengthFOLDINFO = BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadInt32(); // 9
//[TEXT]->8Byte
BinReader.ReadChars(8); // GameInfo
//[BYTE] // ???
BinReader.ReadByte();
//[KEYWORD](FOLDWAN) // START OF NEW CHUNK
BinReader.ReadChars(8); // FOLDWMAN
//[DWORD] // ???
BinReader.ReadInt32(); // 1
//[DWORD] // ???
BinReader.ReadInt32();
//[DWORD] // ???
BinReader.ReadInt32();

//[KEYWORD](DATASDSC) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] // Chunk version (?) always 1 so far 2 for Version 4
BinReader.ReadInt32();
//[DWORD] // Chunk data size
BinReader.ReadInt32();
//[DWORD] // A variable string length
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//[DWORD] // Number of teams (?)
BinReader.ReadInt32();
//[DWORD] // Number of active players (without spectators)
this.Replay.PlayerCount = BinReader.ReadInt32();
//[DWORD] // Map Size
this.Replay.Size = BinReader.ReadInt32();
//[DWORD] // String length
num = BinReader.ReadInt32();
if(num > 0)
{
//[TEXT] // Game/engine name
chr = BinReader.ReadChars(num);
this.Replay.MOD = str = new string(chr);
}
else
{
//[DWORD] // Game/engine name
BinReader.ReadInt32();
}
//[DWORD]->%length% // length of additional header infos
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte engine version string (%length%*2)
buffer = BinReader.ReadBytes(num * 2);
this.Replay.Engine = encoding1.GetString(buffer);
//[DWORD]->%length% // lenth of map Name
num = BinReader.ReadInt32();
//[TEXT] // Map name (%length%)
chr = BinReader.ReadChars(num);
this.Replay.Map = str = new string(chr);
//[DWORD] // (?)
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//
//{REP VERSION 1}
if(this.Replay.Version == 1)
{
//[DWORD] // (?)
BinReader.ReadInt32();
//[BYTE] // (?)
BinReader.ReadByte();
//[KEYWORD](FOLDMODI) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] // Chunk version (?) always 1 so far
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//[DWORD] // (?)
BinReader.ReadInt32();
//[KEYWORD](DATADMOD) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] // Chunk version (?) always 4 so far
BinReader.ReadInt32();
//[DWORD]->%length% // Chunk data size
num = BinReader.ReadInt32();
//[TEXT] // (?) (%length%)
chr = BinReader.ReadChars(num);
str = new string(chr);
//[TEXT] // (?)
BinReader.ReadInt32();
//[KEYWORD](DATABASE) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] // Chunk version (?) always 4 so far
BinReader.ReadInt32();
//{END VERSION 1}
//
}
else if(this.Replay.Version == 2 || this.Replay.Version == 4)
{
//{REP VERSION 2}
//[KEYWORD](DATABASE) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] // Chunk version (?) always 4 so far
BinReader.ReadInt32();
//{END VERSION 2}
//
}
//[DWORD] // Chunk data size
this.Replay.BeginDATABASE = BinReader.BaseStream.Position;
this.Replay.LengthDATABASE = BinReader.ReadInt32();
//[DWORD] // Always 0 so far
BinReader.ReadInt32();
//[DWORD] // Always 3 so far
BinReader.ReadInt32();
//[DWORD] // Avavible Slots (after Patch 1.3 always 8 cause spec slots)
this.Replay.Slots = BinReader.ReadInt32();
//[DWORD] // (?)
int gr = BinReader.ReadInt32();
//[DWORD] // Always 8 so far
BinReader.ReadInt32();
//[DWORD] // (?)
int um = BinReader.ReadInt32();
//MessageBox.Show(this.Replay.Slots.ToString() + ": " + um.ToString());
//
for(counter=0;counter < 8;counter++)
{
//{8 Keytext with 1byte value - not sorted!}
//[DWORD] FDIA //= AIDF (AI Difficulty) - It took me a while to figure these out...backwards-endian
//[DWORD] // 1. Byte is the value
//[DWORD] TSSR //= RSST (Starting Resources)
//[DWORD] // 1. Byte is the value
//[DWORD] MTKL //= LKTM (Lock Teams)
//[DWORD] // 1. Byte is the value
//[DWORD] AEHC //= CHEA (Cheats Enabled)
//[DWORD] // 1. Byte is the value
//[DWORD] COLS //= SLOC (Starting Location)
//[DWORD] // 1. Byte is the value
//[DWORD] DPSG //= GSPD (Game Speed)
//[DWORD] // 1. Byte is the value
//[DWORD] HSSR //= RSSH (Resource Sharing)
//[DWORD] // 1. Byte is the value
//[DWORD] TRSR //= RSRT (Resource Rate)
//[BYTE] // The Byte is the value
chr = BinReader.ReadChars(4);
str = new string(chr);

if(counter == 7)
{
// Warum auch immer aber im letzen durchgang ist es eben nur ein byte
wincondvalue = BinReader.ReadByte();
}
else
{
wincondvalue = Convert.ToByte(BinReader.ReadInt32());
}
switch (str)
{
case "FDIA":
this.Replay.GameSetting.AIDiff = wincondvalue;
break;
case "TSSR":
this.Replay.GameSetting.StartRes = wincondvalue;
break;
case "MTKL":
this.Replay.GameSetting.LockTeams = wincondvalue;
break;
case "AEHC":
this.Replay.GameSetting.CheatsON = wincondvalue;
break;
case "COLS":
this.Replay.GameSetting.StartLocation = wincondvalue;
break;
case "DPSG":
this.Replay.GameSetting.GameSpeed = wincondvalue;
break;
case "HSSR":
this.Replay.GameSetting.ResShare = wincondvalue;
break;
case "TRSR":
this.Replay.GameSetting.ResRate = wincondvalue;
break;
}
}
//
this.Replay.NameStart = BinReader.BaseStream.Position;
//[DWORD]->%length% // length of ingame Name
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte game name (%length% * 2)
buffer = BinReader.ReadBytes(num * 2);
this.Replay.Name = encoding1.GetString(buffer);
//[DWORD] // End of Gamename Always 0 so far
BinReader.ReadInt32();
//MessageBox.Show("Header Done...");

//[DWORD]->%length% // This is the number of Win conditions that are set. Each one is a constant DWORD that follows.
counter = BinReader.ReadInt32();
//
for(int win_count=0;win_count < counter;win_count++)
{
//{%length% win conditions}
//[DWORD] // Win conditon
//767227721 Annihilate
//-1826760460 SuddenDeath
//200405640 Assassinate
//-242444938 EconomicVictory
//735076042 ControlArea
//1509920563 DestroyHQ
//1959084950 TakeandHolde
//69421273 GameTime
num = BinReader.ReadInt32();

if(num.Equals(WinCondition.WinConditions.Annihilate)) // Annihilate
{
this.Replay.WinCondition.Annihilate = true;
}
else if(num.Equals(WinCondition.WinConditions.SuddenDeath)) // SuddenDeath
{
this.Replay.WinCondition.SuddenDeath = true;
}
else if(num.Equals(WinCondition.WinConditions.Assassinate)) // Assassinate
{
this.Replay.WinCondition.Assassinate = true;
}
else if(num.Equals(WinCondition.WinConditions.EconomicVictory)) // EconomicVictory
{
this.Replay.WinCondition.EconomicVictory = true;
}
else if(num.Equals(WinCondition.WinConditions.ControlArea)) // ControlArea
{
this.Replay.WinCondition.ControlArea = true;
}
else if(num.Equals(WinCondition.WinConditions.DestroyHQ)) // DestroyHQ
{
this.Replay.WinCondition.DestroyHQ = true;
}
else if(num.Equals(WinCondition.WinConditions.TakeandHolde)) // TakeandHolde
{
this.Replay.WinCondition.TakeandHolde = true;
}
else if(num.Equals(WinCondition.WinConditions.GameTime)) // GameTime
{
this.Replay.WinCondition.GameTime = true;
}
//{END Win Conditions}
}

this.Replay.PlayerStart = BinReader.BaseStream.Position;
return true;
}
else
{
return false;
}
}
#endregion
#region ReadPlayer
private void ReadPlayer()
{
this.Player = new Player();
//{Now for any Slot There come Player data
//[KEYWORD](FOLDGPLY) // START OF NEW CHUNK - GPLY = Game Player? There is one of these chunks for each player.
//MessageBox.Show("New Player at: " + BinReader.BaseStream.Position.ToString() + " (" + str + ")");
chr = BinReader.ReadChars(8);
str = new string(chr);

if(str.Equals("FOLDGPLY"))
{
//[DWORD] 2 // Chunk version (?) Always 2 so far
BinReader.ReadInt32();
//[DWORD] 41330 // Chunk data size
int zzz = BinReader.ReadInt32();
//MessageBox.Show(zzz.ToString() + " / " + BinReader.BaseStream.Position.ToString());
//[DWORD] 0 // A variable string length Always 0 so far
BinReader.ReadInt32();
//[KEYWORD](DATAINFO) // START OF NEW CHUNK
BinReader.ReadInt64();
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 54 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // A variable string length Always 0 so far
BinReader.ReadInt32();
//[DWORD]->%length% // length of Plyer Name
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte player name (%length% * 2)
buffer = BinReader.ReadBytes(num * 2);
this.Player.Name = encoding1.GetString(buffer);
//[DWORD] // Type of Slot (0 Host/2 player/4 specc/7 empty/1,3,11 computer)
this.Player.Type = BinReader.ReadInt32();
//[DWORD] // Team of the Player (counter starts with 0)
this.Player.Team = (BinReader.ReadInt32() + 1);
//[DWORD]->%length% // lengt of race string
num = BinReader.ReadInt32();
//[TEXT] // Race Name (%length%)
chr = BinReader.ReadChars(num);
this.Player.Race = new string(chr);
//[DWORD] // (?) Always 0 so far
BinReader.ReadInt32();
//
if(this.Replay.Version == 4)
{
//[DWORD] // (?) Always 0 so far
num = BinReader.ReadInt32();
//[TEXT] // ?
chr = BinReader.ReadChars(num);

//After Version 1.5 there was this new Flag.
//It is only present in Version > 1.5
//[BYTE] ???
byte tmp = BinReader.ReadByte();
if(tmp > 0)
{
BinReader.BaseStream.Seek(-1, System.IO.SeekOrigin.Current);
}
}
// If there are Empty Slots don't read to fare for the last slot
if(this.Player.Type != 7)
{
//[KEYWORD](FOLDTCUC) // START OF NEW CHUNK - TCUC = Team Colors, something, something?
chr = BinReader.ReadChars(8);
str = new string(chr);

//{Also Possible: FOLDGPLY -> New Player beginns (happens with spec slots)}
if(str == "FOLDTCUC")
{
//
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 84 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // A variable string length Always 0 so far
BinReader.ReadInt32();
//[KEYWORD](DATALCIN) // START OF NEW CHUNK - LCIN = Local?? NOTE: This section differs for the replay's "local" player
BinReader.ReadChars(8);
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD]->%length% 12 // Chunk data size
num = BinReader.ReadInt32();
//[TEXT] // (?) (%length%)
chr = BinReader.ReadChars(num);
//[DWORD] // (?) Always 0 so far
BinReader.ReadInt32();
//[KEYWORD](DATAUNCU) // START OF NEW CHUNK - UNCU = ????
BinReader.ReadChars(8);
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 32 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // A variable string length Always 0 so far
BinReader.ReadInt32();
//[DWORD]->%length% // length of ColorScheme
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte scheme name (%length% * 2)
buffer = BinReader.ReadBytes(num * 2);
str = encoding1.GetString(buffer);
//[DWORD] // Primary NOTE: Colors are BGRA (blue, green, red, alpha)
buffer = BinReader.ReadBytes(4);
this.Player.Primary = Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]);
//[DWORD] // Secondary
buffer = BinReader.ReadBytes(4);
this.Player.Secondary = Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]);
//[DWORD] // Trim
buffer = BinReader.ReadBytes(4);
this.Player.Trim = Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]);
//[DWORD] // Weapons
buffer = BinReader.ReadBytes(4);
this.Player.Weapons = Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]);
//[DWORD] // Eyes
buffer = BinReader.ReadBytes(4);
this.Player.Eyes = Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]);
//
for(int bannerbadge=0; bannerbadge < 2 ;bannerbadge++)
{
//[KEYWORD](FOLDTCBD) // START OF NEW CHUNK - TCBD = Team color Badge?
chr = BinReader.ReadChars(8);
str = new string(chr);
//{Also Possible: FOLDGPLY -> New Player beginns (happens sometimes...)}
//{Another keyword FOLDTCBD -> Badge/Banner sometimes change their position in the Replay}
//{If none of this Keywords is matchetd it seams like an broken header.. So ignore the 8byte keyword and go on with action data}
//
if(str.Equals("FOLDTCBD"))
{
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 16460 // Chunk data size - A bigish chunk...hence the transferring badges lag
BinReader.ReadInt32();
//[DWORD] 0 // A variable string length
BinReader.ReadInt32();
//[KEYWORD](FOLDIMAG) // START OF NEW CHUNK - IMAG = Image (badge in this case)
chr = BinReader.ReadChars(8);
str = new string(chr);
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 16460 // Chunk data size
BinReader.ReadInt32();
//[DWORD]->%length% // A variable string length
num = BinReader.ReadInt32();
//{IF %length% GT 0 then the Badge has a special Name}
//[TEXT] // Name of the Badge (%length%)
chr = BinReader.ReadChars(num);
str = new string(chr);
//{END}
//[KEYWORD](DATAATTR) // START OF NEW CHUNK - ATTR = Image attribute(s)?
chr = BinReader.ReadChars(8);
str = new string(chr);
//[DWORD] 2 // Chunk version (?) Always 2 so far
BinReader.ReadInt32();
//[DWORD] 16 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//[DWORD] 64 // Image HEIGHT
int height = BinReader.ReadInt32();
//[DWORD] 64 // Image WIDTH
int width = BinReader.ReadInt32();
//[DWORD] 1 // (?) Always 1 so far
BinReader.ReadInt32();
//[KEYWORD](DATADATA) // START OF NEW CHUNK - DATA = Image data?
chr = BinReader.ReadChars(8);
str = new string(chr);
//[DWORD] 2 // Chunk version (?) Always 2 so far
BinReader.ReadInt32();
//[DWORD] 16 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//
//{Now comes the image data. Pixel by pixel form heigth to width in RGBA colors - you also have to mirror the picture}
this.Player.Badge = new Bitmap(width, height);
for(int y =0;y<height;y++)
{
for(int x=0;x<width;x++)
{
buffer = BinReader.ReadBytes(4);
this.Player.Badge.SetPixel(x, y, Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]));
}
}
this.Player.Badge.RotateFlip(RotateFlipType.Rotate180FlipX);

//
}
else if(str.Equals("FOLDTCBN"))
{
//
//[KEYWORD](FOLDTCBN) // START OF NEW CHUNK - TCBN = Team color Banner?
//Already done
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 24652 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//[KEYWORD](FOLDIMAG ) // START OF NEW CHUNK - IMAG = Image (banner in this case)
BinReader.ReadInt64();
//[DWORD] 1 // Chunk version (?) Always 1 so far
BinReader.ReadInt32();
//[DWORD] 1152 // Chunk data size
BinReader.ReadInt32();
//[DWORD]->%length% // A variable string length
num = BinReader.ReadInt32();
//{IF %length% GT 0 then the Banner has a special Name}
//[TEXT] // Name of the Banner (%length%)
chr = BinReader.ReadChars(num);
str = new string(chr);
//[KEYWORD](DATAATTR) // START OF NEW CHUNK - ATTR = Image attribute(s)?
BinReader.ReadInt64();
//[DWORD] 2 // Chunk version (?) Always 2 so far
BinReader.ReadInt32();
//[Word] 16 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//[DWORD] 64 // Image WIDTH
int width = BinReader.ReadInt32();
//[DWORD] 96 ´ // Image HEIGHT
int height = BinReader.ReadInt32();
//[DWORD] 1 // (?) Always 1 so far
BinReader.ReadInt32();
//[KEYWORD](DATADATA) // START OF NEW CHUNK - DATA = Image data?
BinReader.ReadInt64();
//[DWORD] 2 // Chunk version (?) Always 2 so far
BinReader.ReadInt32();
//[DWORD] 1536 // Chunk data size
BinReader.ReadInt32();
//[DWORD] 0 // (?)
BinReader.ReadInt32();
//
//{Now comes the image data. Pixel by pixel form heigth to width in RGBA colors - you also have to turn the picture}
this.Player.Banner = new Bitmap(width, height);
for(int y =0;y<height;y++)
{
for(int x=0;x<width;x++)
{
buffer = BinReader.ReadBytes(4);
this.Player.Banner.SetPixel(x, y, Color.FromArgb(buffer[3], buffer[2], buffer[1], buffer[0]));
}
}
this.Player.Banner.RotateFlip(RotateFlipType.Rotate180FlipX);
}
else
{
//Header was not closed correct happend in some replays in <=1.3
//So just leave the loop an say we got a new Player
bannerbadge = 2;
BinReader.BaseStream.Seek(-8, System.IO.SeekOrigin.Current);
}
}
}
else
{
//Header was not closed correct happend in some replays in <=1.3
//So just leave the loop an say we got a new Player
BinReader.BaseStream.Seek(-8, System.IO.SeekOrigin.Current);
}
}
}
else
{
//Header was not closed correct happend in some replays in <=1.3
//So just leave the loop an say we got a new Player
BinReader.BaseStream.Seek(-8, System.IO.SeekOrigin.Current);
}
}
//
//{End of Player Data}
//MessageBox.Show("Next Player at: " + BinReader.BaseStream.Position.ToString());

#endregion
#region ReadActionDetail
// Chat.SndID gleicher text wie bei actions
private void ReadActionDetail()
{

//[DWORD] // Action Key - Action Key 1 identefies an Chat msg so far
int Action1 = BinReader.ReadInt32();
//[DWORD] // Action Length
int Action1Len = BinReader.ReadInt32();

int ReadedActionLen = 0;
//MessageBox.Show(BinReader.BaseStream.Position.ToString() + " / " + Action1Len.ToString());
if(Action1.Equals(1))
{
//[DWORD] // Action Key
int Action2 = BinReader.ReadByte();
//{IF this action key is also 1 its an chat msg}
if(Action2.Equals(1))
{
// [BYTES] 3 empty Bytes
BinReader.ReadBytes(3);

this.Chat = new ChatMessage();
//[DWORD] // Length of Chat chunk
BinReader.ReadInt32();
//[BYTE] // Also length of Chat chunk so far
BinReader.ReadByte();
//{IF REP Version 1}
if(this.Replay.Version == 1)
{
//[BYTE] // Player ID (As same orders as they are listed bevore)
this.Chat.Snd = BinReader.ReadByte();
//[BYTE] // Reciver 0 All/1 Team/2 System
this.Chat.Rec = BinReader.ReadByte();
//[BYTE] // (?)
BinReader.ReadByte();
//{IF Rep Version 2}
}
else if(this.Replay.Version == 2 || this.Replay.Version == 4)
{
//MessageBox.Show(BinReader.BaseStream.Position.ToString());
//[DWORD]->%len% // Length of Player Name
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte player name (%len% * 2)
buffer = BinReader.ReadBytes(num * 2);
this.Chat.SndName = encoding1.GetString(buffer);
//[DWORD] // Player ID > 1000 are normal players blow the IDs of the Spectators
this.Chat.Snd = BinReader.ReadInt32();
//MessageBox.Show(this.Chat.Snd.ToString());
//[DWORD] // Msg Type 0 Player/1 Spec/2 System
this.Chat.Type = BinReader.ReadInt32();
//[DWORD] // Reciver 0 All/1 Team/2 System
this.Chat.Rec = BinReader.ReadInt32();
//{End of Version spec Data}
}
//[DWORD]->%len% // Length of Chat MSG
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte chat msg (%len% * 2)
buffer = BinReader.ReadBytes(num * 2);
this.Chat.Msg = encoding1.GetString(buffer);
//{If second Action Key is not 1}

this.Chat.Zeit = TickToTime(this.LastTick);
this.Replay.ChatMSG.Add(this.Chat);
}
else if(Action2.Equals(Action1Len))
{
// Here was a lag window

//[DWORD]->%length% // length of player
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte player name (%len% * 2)
buffer = BinReader.ReadBytes(num * 2);
//[DWORD] // Player id
num = BinReader.ReadInt32();
//[DWORD] ???
num = BinReader.ReadInt32();
//[DWORD] ???
num = BinReader.ReadInt32();
//[DWORD]->%length% // length of text
num = BinReader.ReadInt32();
//[UNICODETEXT] // Double-byte text ??? (%len% * 2)
buffer = BinReader.ReadBytes(num * 2);
}
else
{
// [BYTES] 3 empty bytes
BinReader.ReadBytes(3);
//[DWORD]->%length% // length of action
num = BinReader.ReadInt32();
//[BYTE] // (?)
BinReader.ReadByte();
//[TEXT] // (?) (%length%)
BinReader.ReadBytes(num);
//BinReader.ReadBytes(num);
}
//{If action key not is 1}
}
else if(Action1 == 0 && Action1Len > 14)
{

//[BYTE] ???
BinReader.ReadByte(); // Always 80 ??
if(this.Replay.Version > 1)
{
//[BYTE] Marks if action block contains actions
BinReader.ReadByte(); // If 1 Action Block has action!
}

//[DWORD] Tick of this action
int Tick = BinReader.ReadInt32();
this.LastTick = Tick;

//[DWORD] Total number of actions so fare
this.Replay.ActionCount = BinReader.ReadInt32(); // ActionCounter

//[DWORD] ??? Move Data ?
BinReader.ReadInt32(); // MoveData

ReadedActionLen = 12; // 12 Bytes Already read

//[DWORD] Length of the complete action part
BinReader.ReadInt32();
//[BYTE] Single byte ???
BinReader.ReadByte();

ReadedActionLen = ReadedActionLen + 5;

// Only read till action ends
while(ReadedActionLen < Action1Len)
{
try
{
// Create new action
Action CurrentAction = new Action();
//[BYTE] length of simple Action
CurrentAction.ActionLen = BinReader.ReadByte();
ReadedActionLen = ReadedActionLen + 1;

//// [BYTES] -> 14 ???
CurrentAction.ActionData = BinReader.ReadBytes(14);
BinReader.BaseStream.Seek(-14, System.IO.SeekOrigin.Current);

// [BYTE] always 0
BinReader.ReadByte();

// [WORD] ???
BinReader.ReadInt32();

// [WORD] Action kind
CurrentAction.Kind = BinReader.ReadInt32();

// [WORD] Action kind value
CurrentAction.KindValue = BinReader.ReadInt32();

// [BYTE] always 0
BinReader.ReadByte();

// [INT16] Action Player after 1.3 startlocation + 1000
CurrentAction.ActionPlayer = BinReader.ReadInt16();
if(this.Replay.Version < 2 && this.Replay.Version > 1)
{
CurrentAction.ActionPlayer = (Int16) (CurrentAction.ActionPlayer + 1000);
}
// [INT16] Action Player2 seams to be always the same
CurrentAction.ActionPlayer2 = BinReader.ReadInt16();
// [INT16] Action Player action counter for this player
Int16 PlayerActionCounter = BinReader.ReadInt16();

// [BYTES] Action Data ??? length = ActionLen - 21
CurrentAction.ActionData2 = BinReader.ReadBytes(CurrentAction.ActionLen - 1 - 14 - 6);
ReadedActionLen = ReadedActionLen + CurrentAction.ActionLen + 1;

if(CurrentAction.ActionPlayer >= 1000)
{
//MessageBox.Show("Fehler ??? bei Sekunde: 1 " + CurrentAction.ActionPlayer.ToString());
//Add reades action to the player (not correct till now!)
Player ThisActionPlayer = (this.Replay.Player[CurrentAction.ActionPlayer - 1000] as Player);
//MessageBox.Show("Fehler ??? bei Sekunde: 2 " + CurrentAction.ActionPlayer.ToString());

ThisActionPlayer.ActionCount = PlayerActionCounter;
ThisActionPlayer.LastActionTick = Tick;

CurrentAction.Tick = Tick;
CurrentAction.Second = System.Convert.ToInt16(Tick / 8);

ThisActionPlayer.Actions.Add(CurrentAction);

this.Replay.Player[CurrentAction.ActionPlayer - 1000] = ThisActionPlayer;
}
else{
//CurrentAction.Second = System.Convert.ToInt16(Tick / 8);
//MessageBox.Show("Fehler ??? bei Sekunde: " + CurrentAction.Second.ToString() + " Player: " + CurrentAction.ActionPlayer.ToString());
}
}
catch
{
//MessageBox.Show("Fehler bei: " + BinReader.BaseStream.Position.ToString() + " Action: " + Action1.ToString() + " (" + Action1Len.ToString() + ")");
}
}
}
else
{
BinReader.ReadBytes(Action1Len);
// If empty action just read the action lenght
//BinReader.ReadBytes(Action1Len);
}
}
#endregion
#region GetReplayInformation
public bool GetReplayInformation(string FileName)
{
if(this.ReadHeader(FileName))
{
for(int players = 0; players < this.Replay.Slots; players++)
{
this.ReadPlayer();
this.Replay.Player.Add(this.Player);
}

this.Cache.Add(FileName,this.Replay);

this.BinReader.Close();
return true;
}
else
{
this.BinReader.Close();
return false;
}
}
#endregion
#region ReadReplay
public bool ReadReplay(string FileName)
{

if(this.ReadReplayOnly(FileName))
{
//Raise Event for Handlers
this.ReplayChanged(this, EventArgs.Empty);
return true;
}
else
{
return false;
}
}
#endregion
#region ReadReplayOnly
public bool ReadReplayOnly(string FileName)
{
if(this.ReadHeader(FileName))
{
if(this.Cache == null)
{
this.Cache = new Analyse(true);
}
//MessageBox.Show("Body Start...");
for(int players = 0; players < this.Replay.Slots; players++)
{
this.ReadPlayer();
this.Replay.Player.Add(this.Player);
}
this.Replay.ActionStart = BinReader.BaseStream.Position;

//MessageBox.Show("Body Done...");


//MessageBox.Show("Actions Start... (AT:" + BinReader.BaseStream.Position.ToString() + ")");
//{Now The acion Data starts.. DoW is working with 8Ticks per second}
while (BinReader.BaseStream.Position < BinReader.BaseStream.Length)
{
this.ReadActionDetail();
}

//MessageBox.Show("Actions Done...");

this.BinReader.Close();
this.Cache.Add(FileName,this.Replay);
return true;
}
else
{
this.BinReader.Close();
return false;
}
}
#endregion
}
}


"еще немного информации из инструмента debug менеджера AutoSave replays"

recformat.txt by hype[NZ]

-----------------------------------------------------------------------------
TYPE 0 CHUNK - EMPTY CHUNK
-----------------------------------------------------------------------------

00 00 00 00 \\ type 0 chunk... ordinary chunk
11 00 00 00 \\ length of chunk in this case length 17, implying empty chunk
50 \\ (P or 80) this is followed by the tick number
94 01 00 00 \\ tick number, starts at 01 00 00 00

6B 00 00 00 \\ number of actions performed in total.
\\ Doesn't count messages. Is only incremented after an action
\\ containing chunk has been performed, starts at 00 00 00 00

D6 78 72 72 \\ 'random' number generated during the game to calculate whether projectiles hit etc.
00 00 00 00 \\ no action - in this example this was an empty chunk

-----------------------------------------------------------------------------
TYPE 1 CHUNK - MESSAGING AND CHAT
-----------------------------------------------------------------------------

01 00 00 00 \\ chunk begins, type 1 so chat
3F 00 00 00 \\ length of chunk = 63
01 00 00 00 \\ chat version 1 (haven't seen any others yet)
36 00 00 00 \\ length until end of chunk
36 \\ byte containing same info afaik
0A 00 00 00 \\ length of player name, 10 here
l i n d e l o k s e \\ Player name, 10 double-bytes
EA 03 00 00 \\ Player ID [00 00 00 00 is observer (?)]
00 00 00 00 \\ message type, 0 = player, 1 = observer, 2 = system
00 00 00 00 \\ receiver, 0 = all, 1 = team, 2 = system
07 00 00 00 \\ length of message, 7 here
l i k e m e \\ message, 7 double-bytes


-----------------------------------------------------------------------------
BUILD SCOUT - FULL CHUNK EXAMPLE
-----------------------------------------------------------------------------

hype build scout Yao build scout \\ comments for Yao build scout
00 00 00 00 00 00 00 00 \\ type 0
3A 00 00 00 3A 00 00 00 \\ length 80
50 50 \\ P
A5 01 00 00 51 00 00 00 \\ timestamp 81
03 00 00 00 00 00 00 00 \\ total actions so far, this is the first
83 5E 0E 32 67 B2 68 92 \\ 'random number'
01 00 00 00 01 00 00 00 \\ one action in this chunk
0F 9E 82 29 9B 6A 75 53 \\ true multiplayer ID (in skirmish this is 00 00 00 00)
00 00 00 00 00 00 00 00 \\ all actions seem to have this so far
1C 00 00 00 1C 00 00 00 \\ length remaining
1C 1C 00 1C 1C 00 \\ length remaining byte, length remaining 2byte
B8 25 0D 00 B6 11 0D 00 \\ ??? depends on the player though (resources ???)
03 00 00 00 03 00 00 00 \\ build unit
73 73 \\ unit is scout
03 00 00 00 03 00 00 00 \\ build unit
E9 03 E9 03 E8 03 E8 03 \\ player ID
00 00 00 00 \\ number of actions by player
01 02 01 02 \\ 01 is number of things selected \\ 02 refers to building (01 = builder ???, 02 = building, 03 = unit)
69 67 \\ this is ingame building ID
05 00 00 00 05 00 00 00 \\ ???

\\ footnote: it seems that the scout's ID is not assigned here, rather the game assigns newly built units a specific number based on order built
\\ e.g. in a 1v1,
\\ 1st player servitor would be 50 C3 00 00 (dec 50000)
\\ 2nd player servitor would be 51 C3 00 00 (dec 50001)
\\ next unit built would be 52 C3 00 00 (dec 50002)
\\ etc
-----------------------------------------------------------------------------
UNIT COMMANDS
-----------------------------------------------------------------------------
> moving 4 squads around 2x scouts 2x tacs (subchunk only, west endian)
23 00 \\ length
D2 36 61 00 \\ mystery number
00 00 00 00 \\
00 \\
00 00 00 00 \\ move command
9E 30 9E 30 \\ player ID
32 00 \\ number of player actions so far
40 \\ 4 squads selected
30:95 3C 00 00 \\ unit ID marker:unit ID
30:85 3C 00 00
30:55 3C 00 00
30:65 3C 00 00
10 \\ ???
00 \\ move
3E EF \\ x ???
82 00 \\ y ???
D4 EF \\ z ???

> perform action on target (e.g. squads will attack an enemy, resume building a structure etc)
12 00
0D 31 71 00
00 00 00 00
00
00 00 00 00
9E 30 9E 30
92 00
10 \\ 01 - 1 unit selected
30:95 3C 00 00 \\ unit ID ... builder is 60:xx xx xx xx
10 70 \\ ?? always 01 \\ 07 = perform action on target (e.g. attack, build, repair) ??
57 50
00 00

-----------------------------------------------------------------------------
BUILDING STUFF
-----------------------------------------------------------------------------
------------------------------
GLOBAL STUFF
------------------------------
CANCEL UNIT SUBCHUNK
Each building records the list of units started in order. The code to cancel is just
the order in which the unit was started, even if it was started 20 mins later.
e.g. serv scout scout scout scout-> cancel 3rd scout, wait 20 mins serv -> cancel serv

cancel codes will be 05 and then 06

C1 00 \\length
FB 3E 1B 10 \\ ??? (syncing ???)
40 00 00 00 \\ primary command (cancel unit)
10 \\ cancel first unit in queue, see note above
00 00 00 00 \\ secondary command (none)
8E 30 8E 30 \\ player ID (1001)
40 00 \\ player actions
10 20 \\ 01 selected, 02 = building (for SM)
76 \\ building ID (could be 76 50 00 00, which would imply the next byte 00 means 'nothing to follow'
50 00 00 00 \\ ???

---------------------------------
SPACE MARINE build stuff subchunk
---------------------------------
(west endian)
> SPACE MARINE - build structure subchunk
82 00 \\ length remaining
AB D1 01 00
57 00 00 00 \\ servitor -> build something command (?)
97 \\ 77 = sacred artifact\\ 78 = armoury\\ 79 = rax\\ 7B = gen\\ 7C = HQ\\ 7F = lp
\\ 80 = mines\\ 81 orbital relay\\ 86 Big Gen\\ 87 = turret\\ 89 = machine cult
20 00 00 00 \\ build building command (02)
8E 30 8E 30
00 00 \\ player actions so far
10 10 \\ 1 unit selected \\ builder
8E 30 00 00 \\ Player ID
20
60:05 3C 00 00 \\ servitor ID
00
0A 00 \\
82 00 \\
8B 10 \\ coordinates (x,y,?)

> SPACE MARINE - build unit subchunk (space marine);
C1 00
55 63 01 00
30 00 00 00 \\ build
67 \\ 52 = Apothecary \\ 54 = ASM \\ 5A = Chaplain \\ 5D = Dreadnaught \\ 63 = Force Commander
\\ 65 = Grey Knight \\ 68 = Landraider \\ 69 = landspeeder \\ 6C = Librarian \\ 6F = predator
\\ 71 = rhino \\ 73 = scout \\ 76 = servitor \\ 7C = tac \\ 7F = Terminators\\ 80 = Assault Terminators \\ 89 = whirlwind
30 00 00 00 \\ build unit command (03)
8E 30 8E 30
10 00
10 20 \\ 1 thing selected \\ 02 => building
76 \\ ingame building ID
50 00 00 00

> SPACE MARINE - addons (tier2, tier3, lp2, lp3 etc)
C1 00
17 B0 B0 00
70 00 00 00
92 \\29 = SM tier 2 \\ 2A = SM tier 3 \\ 2B = SM lp2 \\ 2C = SM lp3 \\2E = missile turret addon
C0 00 00 00
8E 30 8E 30
30 00
10 20
11
60 00 00 00

> SPACE MARINE - population increase
C1 00
50 D4 70 00
60 00 00 00
AA \\ AA = inf_01 \\ AB = inf_02 \\ AC = inf_03 \\ AD = inf_04 \\
\\ AE = veh_01 \\ AF = veh_02 \\ B0 = veh_03 \\ B1 = veh_04 \\
E0 00 00 00
9E 30 9E 30
31 00
10 20
EA
E0 00 00 00

> SPACE MARINE - wargear
C1 00
2F F1 C0 00
60 00 00 00 \\ 70 00 00 00 for HQ wargear
70 \\ 07 = Power Sword + Pistol \\ 09 = Daemonhammer + Melta \\ 10 = Champion Cincture \\ 11 = Iron Halo
\\ 12 = Bracers of the Righteous \\ 13 = Heroism Pedestal \\ 14 = Master Armour \\ 15 = Orbital Strike Wargear
E0 00 00 00 \\ C0 00 00 00 for HQ wargear
9E 30 9E 30
F2 00
10 20
4B \\ building ingame ID
E0 00 00 00
---------------------------
NECRON build stuff subchunk
---------------------------
> NECRON - build unit
C1 00
27 FE 94 00
30 00 00 00
2B \\ B2 = NW \\ B8 = Deceiver \\ BB = Destroyer \\ BD = Flayed \\BF = Heavy Destroyer
\\ C1 = Immortal \\ C4 = Destroyer Lord \\ C5 = Necron Lord \\CB = Pariah \\ D7 = Wraith \\
20 00 00 00
8E 30 8E 30
70 00
10 20
4A
E0 00 00 00

> NECRON - build structure
82 00
86 9F E0 00
57 00 00 00 \\ builder unit build
6A \\ A2 = monolith \\ A6 = Forbidden archives \\ A5 = Energy Core \\ A7 = Greater Summoning Core \\ A8 = LP
\\ A9 = Gen \\ AA = Summoning Core \\ AC = Thermogan \\ AE = turret \\ D5 = tombspyder
10 00 00 00 \\ Structure
9E 30 9E 30
00 00
10 10
9E 30 00 00 \\ player ID again
20
60:45 3C 00 00
00
45 10
B4 00
0D DF

> NECRON - addons
C1 00
EB D5 94 00
70 00 00 00
0D \\ D0 = Necron Tier 2 \\ D1 = Necron tier 3 \\ D3 = lp2 \\ D4 = lp3 \\ D5 = Gauss turret II \\
B0 00 00 00
8E 30 8E 30
50 00
10 20
31 \\ building ingame ID
E0 00 00 00 \\ can be different, but the same throughout each rep

> NECRON - wargear (similar to addons)
C1 00
B9 A7 E4 00
70 00 00 00
B1 \\ 16 = Death Mask \\ 17 = Mantle of Doom \\ 18 = Extinction Claw
\\ 19 = Herald of Woe \\ 1A = Raiment End of times \\ 1B = Heart of Darkness \\
C0 00 00 00
8E 30 8E 30
81 00
10 20
5B
E0 00 00 00

C1 00 \\ from different rep (skirmish)
F2 B0 20 00
60 00 00 00
C2 \\ 2A = NL weapon_01 \\ 2C = NL weaponn_02
E0 00 00 00
8E 30 8E 30
91 00
10 20
D7
50 00 00 00

> NECRON - Summon Nightbringer
12 00
45 B9 F4 00
35 00 00 00 \\ ability (?)
00
00 00 00 00
8E 30 8E 30
B1 00
10 \\ number of units selected
30:26 3C 00 00 \\ Necron Lord ingame ID
10 70 \\ ???
1D E0 \\ ???
00 00 \\ ???

________________________________________________________________________________
_________________________________
COORDINATES: Blood River
/|\
/ | \ x -axis
/ | 2\
left crit/ o \right crit (origin) (1270,1270)
\ | /
\1 | /
\ | /y-axis


north A0 BF 38 00 6F 40 \\ 64266 \\ 131 \\ 1270 \\
east 6F 40 C2 10 6F 40 \\ 1270 \\ 300 \\ 1270 \\
south 6F 40 E3 00 A0 BF \\ 1270 \\ 62 \\ 64266 \\
west A0 BF 66 00 A0 BF \\ 64266 \\ 102 \\ 64266 \\

xx xx zz zz yy yy

start at left crit and go clockwise, all these are just rally monolith
note FB 0A + 04 F6 = FF FF + 1
left crit ** _________________
32 00 E3 8A 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 00 00 10 20 CA 40 00 00 10 00 A0 BF 76 00 A0 BF
32 00 10 9A 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 10 00 10 20 CA 40 00 00 10 00 A0 BF 66 00 A0 BF
32 00 0E 9A 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 20 00 10 20 CA 40 00 00 10 00 A0 BF 66 00 A0 BF
32 00 4B AA 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 30 00 10 20 CA 40 00 00 10 00 A0 BF 66 00 A0 BF
32 00 DA BA 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 40 00 10 20 CA 40 00 00 10 00 A0 BF 66 00 A0 BF

top **
32 00 6D BC 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 60 00 10 20 CA 40 00 00 10 00 A0 BF 38 00 6F 40
32 00 1D CC 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 70 00 10 20 CA 40 00 00 10 00 A0 BF 38 00 6F 40
32 00 BD DC 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 80 00 10 20 CA 40 00 00 10 00 A0 BF 38 00 6F 40
32 00 6C EC 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 90 00 10 20 CA 40 00 00 10 00 A0 BF 38 00 6F 40

right crit **
32 00 37 1E 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 A0 00 10 20 CA 40 00 00 10 00 6F 40 C2 10 6F 40
32 00 64 2E 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 B0 00 10 20 CA 40 00 00 10 00 6F 40 C2 10 6F 40
32 00 02 3E 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 C0 00 10 20 CA 40 00 00 10 00 6F 40 C2 10 6F 40
32 00 90 4E 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 D0 00 10 20 CA 40 00 00 10 00 6F 40 C2 10 6F 40
32 00 8F 4E 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 E0 00 10 20 CA 40 00 00 10 00 6F 40 C2 10 6F 40

harbour **
32 00 5A 8F 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 F0 00 10 20 CA 40 00 00 10 00 6F 40 F3 00 A0 BF
32 00 09 9F 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 01 00 10 20 CA 40 00 00 10 00 6F 40 E3 00 A0 BF
32 00 26 AF 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 11 00 10 20 CA 40 00 00 10 00 6F 40 E3 00 A0 BF
32 00 65 BF 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 21 00 10 20 CA 40 00 00 10 00 6F 40 E3 00 A0 BF
32 00 E4 CF 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 31 00 10 20 CA 40 00 00 10 00 6F 40 E3 00 A0 BF
32 00 E4 CF 3C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 31 00 10 20 CA 40 00 00 10 00 6F 40 E3 00 A0 BF

left crit going clockwise sort of
32 00 F2 A1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 41 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 E2 BF
32 00 3D A1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 51 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 F2 BF
32 00 DA B1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 61 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 B2 BF
32 00 79 C1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 71 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 A2 BF
32 00 E4 D1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 81 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 D4 BF
32 00 5F D1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 91 00 10 20 CA 40 00 00 10 00 A0 BF 72 00 44 CF
32 00 DA E1 4C 00 E0 00 00 00 00 00 00 00 00 9E 30 9E 30 A1 00 10 20 CA 40 00 00 10 00 A0 BF 82 00 32 CF




Сообщение отредактировал USSRxAZ - 12.04.2011, 18:42


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
_Master_
сообщение 12.04.2011, 20:07
Сообщение #2


Hero
********

Группа: Пользователь
Сообщений: 488
Регистрация: 23.12.2009
Пользователь №: 21 501



Репутация:   80  


Где же перенесенная дискуссия?
Перейтик к верху страницы
 
+Цитировать сообщение
USSRxAZ
сообщение 12.04.2011, 21:31
Сообщение #3


Blackened
Maniac!
************

WH40k: Dawn of War II
Раса: Eldar
Армия: Farseer
Группа: Администратор
Сообщений: 3 366
Регистрация: 02.11.2006
Из: Новороссийск
Пользователь №: 6 400



Репутация:   1309  


пускай там лежит, там не так много конкретных утверждений


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
переведунец
сообщение 12.04.2011, 23:12
Сообщение #4


Apprentice
***

Группа: Пользователь
Сообщений: 60
Регистрация: 24.09.2010
Пользователь №: 25 209



Репутация:   3  


Цитата(_Master_ @ 12.04.2011, 20:07) *
Где же перенесенная дискуссия?

А самому слабо?

Цитата(_Master_ @ 12.04.2011, 16:22) *
2 Ламо: Вот тут достаточно всяких примеров.

Прикрепленный файл  говносайт.png ( 227.84 килобайт ) Кол-во скачиваний: 39

Постарайся обойтись без ссылок на г@вносайты. Кидай реплеи с синками без обсов (желательно сразу все одним архивом), или с синками во время простоя прямо сюда.

Цитата(_Master_ @ 12.04.2011, 16:22) *
2 Морти: Считаю, что разрыв цепочки можно восстановить, исключив выпавшее звено.

Похоже с первого раза смысл написанного Морталесом до тебя не дошел. Бывает, но чтобы продолжать дискуссию, тебе необходимо перечитать его сообщение, еще и еще, пока не придет озарение.

Цитата(Goblin47 @ 12.04.2011, 15:54) *
Даже без обсов синк эроры происходят. Почему-то они чаще всего происходят, когда в играх есть некроны.

Синки связаны не непосредственно с обсами, а со сворачиваниями игры. Но естественно, что сворачиваются прежде всего обсы. А что касается некронов - видимо в силу особенностей геймплея, они находят время и посредине игры свернуться без ушерба для контроля.

Сообщение отредактировал переведунец - 12.04.2011, 23:12
Перейтик к верху страницы
 
+Цитировать сообщение
_Master_
сообщение 13.04.2011, 06:37
Сообщение #5


Hero
********

Группа: Пользователь
Сообщений: 488
Регистрация: 23.12.2009
Пользователь №: 21 501



Репутация:   80  


Если ничего не делать - ничего и не получится.
Хотелось бы узнать для начала - как изменяется структура реплея при синк эрроре. Т. е. на каком временном интервале выпадает синхронизация игровых событий? (Для того, чтобы понимать объем работ по посстановлению реплея).
Считаю, что синхронизация - дело восстановимое, иначе бы игра он-лайн также останавливалась при критическом альт-табе smile.gif
Значит остается поднять механизм самовосстановления и использовать его в деле восстановления реплеев.
Да вообще, считаю, что методов решения различных программных задач множество! Даже не стану приводить примеры - сами все знаете.
Надо работать над тем как ЭТО СДЕЛАТЬ, а не "всё потеряно! Мы все умрём!"
Перейтик к верху страницы
 
+Цитировать сообщение
переведунец
сообщение 13.04.2011, 07:22
Сообщение #6


Apprentice
***

Группа: Пользователь
Сообщений: 60
Регистрация: 24.09.2010
Пользователь №: 25 209



Репутация:   3  


Цитата(_Master_ @ 13.04.2011, 06:37) *
Хотелось бы узнать для начала - как изменяется структура реплея при синк эрроре.

Ты сам с собой чтоли разговариваешь? Тебе уже несколько раз объяснили это, и если ты не можешь понять настолько элементарных вещей, то не стоит даже грезить о восстановлении своими силами.
Все что мы можем сами - это попробовать разобраться в точных причинах ошибок, и если ты хочешь помочь, то будь добр, закинь сюда примеры реплеев о которых ты столько говорил.

Перейтик к верху страницы
 
+Цитировать сообщение
_Master_
сообщение 13.04.2011, 08:35
Сообщение #7


Hero
********

Группа: Пользователь
Сообщений: 488
Регистрация: 23.12.2009
Пользователь №: 21 501



Репутация:   80  


Все объяснения заключались в неподтвержденных суждениях. Я бы хотел разобраться в бинарном коде.
Реплеи нужно сначала найти (просмотрев их как минимум и убедившись, что они без обсов), затем выложить. Это как минимум вечером.
Далее. Хотелось бы поработать с самим менеджером реплеев, т. к. мне мало что дает его исходный код (я не силен в программировании).
Перейтик к верху страницы
 
+Цитировать сообщение
USSRxAZ
сообщение 13.04.2011, 11:24
Сообщение #8


Blackened
Maniac!
************

WH40k: Dawn of War II
Раса: Eldar
Армия: Farseer
Группа: Администратор
Сообщений: 3 366
Регистрация: 02.11.2006
Из: Новороссийск
Пользователь №: 6 400



Репутация:   1309  


я изза этих разговоров почти дописал скрипт аплоада реплея на сайт)


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
mortales
сообщение 13.04.2011, 11:34
Сообщение #9


Flooder God
***********

Группа: Пользователь
Сообщений: 857
Регистрация: 30.07.2009
Пользователь №: 19 358



Репутация:   84  


Цитата
Считаю, что синхронизация - дело восстановимое, иначе бы игра он-лайн также останавливалась при критическом альт-табе

Нет, онлайн игры не при чем. Там ты от сервера все данные получаешь, при чем здесь альт-таб? А тут другая ситуация. Задача, которую ты хочешь решить, мне представляется следующим образом: сначала я зашел в лабиринт, потом повернул налево, потом направо, потом вошел во 2-ой туннель слева, потом опять повернул направо, потом я час блуждал по лабиринту, не запоминая, куда я сворачиваю, потом я покурил у стенки с изображением древнего человека и от того места пошел налево-направо-направо и т. д. Задача: выбраться из лабиринта. Давайте просто восстановим как-нибудь тот фрагмент, когда я блуждал, выбирая случайные направления и не запоминая их, и все будет ок. А если что-то не сойдется, я буду попадать в забавные тупики.

Сообщение отредактировал mortales - 13.04.2011, 11:37


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
_Master_
сообщение 13.04.2011, 11:44
Сообщение #10


Hero
********

Группа: Пользователь
Сообщений: 488
Регистрация: 23.12.2009
Пользователь №: 21 501



Репутация:   80  


Цитата
я изза этих разговоров почти дописал скрипт аплоада реплея на сайт)
А это поможет делу восстановления реплеев?
Цитата
если что-то не сойдется, я буду попадать в забавные тупики
Лучше попадать в забавные тупики, чем сесть где остановился и умереть.

[ Добавлено спустя 8 минут 29 секунд ]

И еще мне не понятно, действительно ли игрой управляет сервер? По моим наблюдениям создаются пиринговые связи между компьютерами игроков. Это видно из консоли, где коннект создается со всеми игроками, косвенно это подтверждает пропорциональное увеличение потока данных в зависимости от количества присутствующих. Если связи пиринговые - то сервер нужен лишь для ведения статистики и возврата в общий чат. Поправьте, если я не прав.

Сообщение отредактировал _Master_ - 13.04.2011, 11:39
Перейтик к верху страницы
 
+Цитировать сообщение
USSRxAZ
сообщение 13.04.2011, 11:46
Сообщение #11


Blackened
Maniac!
************

WH40k: Dawn of War II
Раса: Eldar
Армия: Farseer
Группа: Администратор
Сообщений: 3 366
Регистрация: 02.11.2006
Из: Новороссийск
Пользователь №: 6 400



Репутация:   1309  


Цитата
А это поможет делу восстановления реплеев?

я и не собирался этого делать


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
mortales
сообщение 13.04.2011, 11:47
Сообщение #12


Flooder God
***********

Группа: Пользователь
Сообщений: 857
Регистрация: 30.07.2009
Пользователь №: 19 358



Репутация:   84  


В ДоВ - пиринговые, наверное, а вообще это от игры зависит. Но и не в этом дело.
Цитата
Лучше попадать в забавные тупики, чем сесть где остановился и умереть

Это была ирония, при чем тут "остановиться и умереть"? Напишу яснее: если я прав, восстановить реплей невозможно.

Сообщение отредактировал mortales - 13.04.2011, 11:50


--------------------
Перейтик к верху страницы
 
+Цитировать сообщение
_Master_
сообщение 13.04.2011, 12:01
Сообщение #13


Hero
********

Группа: Пользователь
Сообщений: 488
Регистрация: 23.12.2009
Пользователь №: 21 501



Репутация:   80  


Кроме того напомню про возможность создания собственных серверов (в меню есть такая функция).

[ Добавлено спустя 14 минуты 2 секунды ]

Цитата
при чем тут "остановиться и умереть"
Это тоже была ирония. Напишу яснее: чтобы выяснить прав ты или не прав, нужно хоть что-то попытаться реализовать.
Перейтик к верху страницы
 
+Цитировать сообщение

Ответить на темуЗапустить новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



RSS Текстовая версия Сейчас: 29.03.2024 - 09:15