@@ -42,6 +42,8 @@ class Program
4242 private static string _recording ;
4343 private static string _tibiaDirectory = string . Empty ;
4444
45+ private static bool _convertToNewFormat = false ;
46+
4547 static void ParseArgs ( string [ ] args )
4648 {
4749 foreach ( var arg in args )
@@ -52,34 +54,46 @@ static void ParseArgs(string[] args)
5254 }
5355
5456 var splitArg = arg . Split ( '=' ) ;
55- if ( splitArg . Length != 2 )
57+ if ( splitArg . Length == 1 )
5658 {
57- continue ;
59+ switch ( splitArg [ 0 ] )
60+ {
61+ case "-c" :
62+ case "--convert" :
63+ {
64+ _convertToNewFormat = true ;
65+ }
66+ break ;
67+ default :
68+ break ;
69+ }
5870 }
59-
60- switch ( splitArg [ 0 ] )
71+ else if ( splitArg . Length == 2 )
6172 {
62- case "-r" :
63- case "--recording" :
64- case "--recordings" :
65- {
66- _recording = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
67- }
68- break ;
69- case "-o" :
70- case "--outdirectory" :
71- {
72- _outDirectory = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
73- }
74- break ;
75- case "-t" :
76- case "--tibiadirectory" :
77- {
78- _tibiaDirectory = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
79- }
80- break ;
81- default :
82- break ;
73+ switch ( splitArg [ 0 ] )
74+ {
75+ case "-r" :
76+ case "--recording" :
77+ case "--recordings" :
78+ {
79+ _recording = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
80+ }
81+ break ;
82+ case "-o" :
83+ case "--outdirectory" :
84+ {
85+ _outDirectory = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
86+ }
87+ break ;
88+ case "-t" :
89+ case "--tibiadirectory" :
90+ {
91+ _tibiaDirectory = splitArg [ 1 ] . Replace ( "\" " , "" ) ;
92+ }
93+ break ;
94+ default :
95+ break ;
96+ }
8397 }
8498 }
8599 }
@@ -163,15 +177,32 @@ static void Main(string[] args)
163177 var isOxRecording = filename . EndsWith ( ".oxr" , StringComparison . CurrentCultureIgnoreCase ) ;
164178 if ( isOxRecording )
165179 {
166- // TODO: Handle the client version properly.
167180 // OXR files begin with the client version they were recorded with.
168181 // This will allows us to easily parse recordings from older client versions.
169182 var version = reader . ReadString ( ) ;
170- Console . WriteLine ( version ) ;
183+ Console . WriteLine ( $ "Client version: { version } ") ;
184+ if ( int . TryParse ( version . Replace ( "." , "" ) , out var versionNumber ) )
185+ {
186+ if ( ! Directory . Exists ( $ "ClientData/{ versionNumber } ") )
187+ {
188+ Console . WriteLine ( $ "ClientData directory for version { version } doesn't exist. Falling back to Tibia directory.") ;
189+ }
190+ }
191+ else
192+ {
193+ Console . WriteLine ( $ "Invalid client version at beginning of recording: { version } ") ;
194+ }
171195 }
172196
173197 _file = null ;
174198 var client = new Client ( _tibiaDirectory ) ;
199+ var oxrFile = ( isOxRecording || ! _convertToNewFormat ) ? null :
200+ new BinaryWriter ( File . Open ( Path . Combine ( Path . GetDirectoryName ( filename ) , Path . GetFileNameWithoutExtension ( filename ) + ".oxr" ) , FileMode . Create ) ) ;
201+ if ( oxrFile != null )
202+ {
203+ Console . WriteLine ( "Converting to new format..." ) ;
204+ oxrFile . Write ( client . Version ) ;
205+ }
175206
176207 client . Proxy . OnReceivedServerLoginChallengePacket += ( packet ) =>
177208 {
@@ -228,6 +259,16 @@ static void Main(string[] args)
228259
229260 var size = reader . ReadUInt32 ( ) ;
230261
262+ if ( oxrFile != null )
263+ {
264+ oxrFile . Write ( ( byte ) PacketType . Server ) ;
265+ // Unfortunately, we don't know the timestamp of each packet.
266+ oxrFile . Write ( 0L ) ;
267+ oxrFile . Write ( size ) ;
268+ oxrFile . Write ( reader . ReadBytes ( ( int ) size ) ) ;
269+ reader . BaseStream . Position -= size ;
270+ }
271+
231272 // We don't care about client packets right now, so skip them.
232273 if ( packetType == PacketType . Client )
233274 {
@@ -244,6 +285,14 @@ static void Main(string[] args)
244285 Size = size
245286 } ;
246287
288+ // Tibia10 recordings seem to contain login data (worlds, characters, etc.)
289+ // in their first packet. We don't parse this, and we don't need to, so skip it.
290+ if ( client . VersionNumber <= 11405409 && sequenceNumber == 0 && reader . PeekChar ( ) == 0x28 )
291+ {
292+ reader . BaseStream . Position += size - 8 ;
293+ continue ;
294+ }
295+
247296 reader . BaseStream . Position -= 8 ;
248297 if ( ( reader . BaseStream . Length - reader . BaseStream . Position ) >= message . Size )
249298 {
@@ -260,6 +309,12 @@ static void Main(string[] args)
260309 }
261310 }
262311
312+ if ( oxrFile != null )
313+ {
314+ oxrFile . Close ( ) ;
315+ Console . WriteLine ( "Done" ) ;
316+ }
317+
263318 if ( _file != null )
264319 {
265320 // node towns
0 commit comments