diff --git a/ClassicalSharp/Audio/AudioPlayer.Sounds.cs b/ClassicalSharp/Audio/AudioPlayer.Sounds.cs
index 56263af3f..3b04601f7 100644
--- a/ClassicalSharp/Audio/AudioPlayer.Sounds.cs
+++ b/ClassicalSharp/Audio/AudioPlayer.Sounds.cs
@@ -46,7 +46,7 @@ namespace ClassicalSharp.Audio {
void PlaySound( SoundType type, Soundboard board ) {
if( type == SoundType.None || monoOutputs == null )
return;
- Sound snd = board.PlayRandomSound( type );
+ Sound snd = board.PickRandomSound( type );
snd.Metadata = board == digBoard ? (byte)1 : (byte)2;
chunk.Channels = snd.Channels;
chunk.Frequency = snd.SampleRate;
@@ -72,14 +72,28 @@ namespace ClassicalSharp.Audio {
firstSoundOut = output;
outputs[i] = output;
}
+ if( !output.DoneRawAsync() ) continue;
- if( output.DoneRawAsync() ) {
+ try {
output.PlayRawAsync( chunk );
- return;
+ } catch( InvalidOperationException ex ) {
+ HandleSoundError( ex );
}
+ return;
}
}
+ void HandleSoundError( InvalidOperationException ex ) {
+ ErrorHandler.LogError( "AudioPlayer.PlayCurrentSound()", ex );
+ if( ex.Message == "No audio devices found" )
+ game.Chat.Add( "&cNo audio devices found, disabling sounds." );
+ else
+ game.Chat.Add( "&cAn error occured when trying to play sounds, disabling sounds." );
+
+ SetSound( false );
+ game.UseSound = false;
+ }
+
void DisposeSound() {
DisposeOutputs( ref monoOutputs );
DisposeOutputs( ref stereoOutputs );
@@ -108,6 +122,6 @@ namespace ClassicalSharp.Audio {
outputs[i].Dispose();
}
outputs = null;
- }
+ }
}
}
\ No newline at end of file
diff --git a/ClassicalSharp/Audio/AudioPlayer.cs b/ClassicalSharp/Audio/AudioPlayer.cs
index 4f2a7ef64..031fc5b5d 100644
--- a/ClassicalSharp/Audio/AudioPlayer.cs
+++ b/ClassicalSharp/Audio/AudioPlayer.cs
@@ -12,8 +12,10 @@ namespace ClassicalSharp.Audio {
IAudioOutput[] monoOutputs, stereoOutputs;
string[] musicFiles;
Thread musicThread;
+ Game game;
public AudioPlayer( Game game ) {
+ this.game = game;
game.UseMusic = Options.GetBool( OptionsKey.UseMusic, false );
SetMusic( game.UseMusic );
game.UseSound = Options.GetBool( OptionsKey.UseSound, false );
@@ -45,7 +47,12 @@ namespace ClassicalSharp.Audio {
using( FileStream fs = File.OpenRead( path ) ) {
OggContainer container = new OggContainer( fs );
- musicOut.PlayStreaming( container );
+ try {
+ musicOut.PlayStreaming( container );
+ } catch( InvalidOperationException ex) {
+ HandleMusicError( ex );
+ return;
+ }
}
if( disposingMusic ) break;
@@ -54,6 +61,17 @@ namespace ClassicalSharp.Audio {
}
}
+ void HandleMusicError( InvalidOperationException ex ) {
+ ErrorHandler.LogError( "AudioPlayer.DoMusicThread()", ex );
+ if( ex.Message == "No audio devices found" )
+ game.Chat.Add( "&cNo audio devices found, disabling music." );
+ else
+ game.Chat.Add( "&cAn error occured when trying to play music, disabling music." );
+
+ SetMusic( false );
+ game.UseMusic = false;
+ }
+
bool disposingMusic;
public void Dispose() {
DisposeMusic();
diff --git a/ClassicalSharp/Audio/Soundboard.cs b/ClassicalSharp/Audio/Soundboard.cs
index 0731f5f96..0dad729aa 100644
--- a/ClassicalSharp/Audio/Soundboard.cs
+++ b/ClassicalSharp/Audio/Soundboard.cs
@@ -29,7 +29,7 @@ namespace ClassicalSharp.Audio {
GetGroups();
}
- public Sound PlayRandomSound( SoundType type ) {
+ public Sound PickRandomSound( SoundType type ) {
if( type == SoundType.None )
return null;
string name = soundNames[(int)type];
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index adbbdae1f..ae60df91a 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -171,6 +171,7 @@
+
diff --git a/ClassicalSharp/Model/CustomModel.cs b/ClassicalSharp/Model/CustomModel.cs
index 0ad23c120..04cc97180 100644
--- a/ClassicalSharp/Model/CustomModel.cs
+++ b/ClassicalSharp/Model/CustomModel.cs
@@ -29,10 +29,14 @@ namespace ClassicalSharp.Model {
int texId = p.PlayerTextureId <= 0 ? cache.HumanoidTexId : p.PlayerTextureId;
}
+ internal void ReadSetupPacket( NetReader reader ) {
+
+ }
+
internal void ReadMetadataPacket( NetReader reader ) {
- collisonSize = ReadVector( reader );
- pickingBounds.Min = ReadVector( reader );
- pickingBounds.Max = ReadVector( reader );
+ collisonSize = ReadS16Vec3( reader );
+ pickingBounds.Min = ReadS16Vec3( reader );
+ pickingBounds.Max = ReadS16Vec3( reader );
nameYOffset = reader.ReadInt16() / 256f;
eyeY = reader.ReadInt16() / 256f;
bobbing = reader.ReadUInt8() != 0;
@@ -41,8 +45,8 @@ namespace ClassicalSharp.Model {
internal void ReadDefinePartPacket( NetReader reader ) {
ushort partId = reader.ReadUInt16();
byte type = reader.ReadUInt8();
- Vector3 min = ReadVector( reader );
- Vector3 max = ReadVector( reader );
+ Vector3 min = ReadS16Vec3( reader );
+ Vector3 max = ReadS16Vec3( reader );
}
internal void ReadRotationPacket( NetReader reader ) {
@@ -54,7 +58,7 @@ namespace ClassicalSharp.Model {
}
CustomModelPart[] parts;
- Vector3 ReadVector( NetReader reader ) {
+ Vector3 ReadS16Vec3( NetReader reader ) {
return new Vector3( reader.ReadInt16() / 256f, reader.ReadInt16() / 256f,
reader.ReadInt16() / 256f );
}
diff --git a/ClassicalSharp/Model/ModelCache.cs b/ClassicalSharp/Model/ModelCache.cs
index 89d24623f..2a7e6e371 100644
--- a/ClassicalSharp/Model/ModelCache.cs
+++ b/ClassicalSharp/Model/ModelCache.cs
@@ -13,6 +13,7 @@ namespace ClassicalSharp.Model {
this.game = window;
api = game.Graphics;
}
+ public CustomModel[] CustomModels = new CustomModel[256];
public void InitCache() {
vertices = new VertexPos3fTex2fCol4b[24 * 12];
diff --git a/ClassicalSharp/Network/NetworkProcessor.CPE.cs b/ClassicalSharp/Network/NetworkProcessor.CPE.cs
index 2be1c2e64..a884a74e6 100644
--- a/ClassicalSharp/Network/NetworkProcessor.CPE.cs
+++ b/ClassicalSharp/Network/NetworkProcessor.CPE.cs
@@ -358,108 +358,6 @@ namespace ClassicalSharp {
AddEntity( entityId, displayName, skinName, true );
}
- void HandleCpeDefineBlock() {
- if( !game.AllowCustomBlocks ) {
- SkipPacketData( PacketId.CpeDefineBlock ); return;
- }
- byte id = HandleCpeDefineBlockCommonStart( false );
- BlockInfo info = game.BlockInfo;
- byte shape = reader.ReadUInt8();
- if( shape == 0 ) {
- info.IsSprite[id] = true;
- info.IsOpaque[id] = false;
- info.IsTransparent[id] = true;
- } else if( shape <= 16 ) {
- info.MaxBB[id].Y = shape / 16f;
- }
-
- HandleCpeDefineBlockCommonEnd( id );
- // Update sprite BoundingBox if necessary
- if( info.IsSprite[id] ) {
- using( FastBitmap dst = new FastBitmap( game.TerrainAtlas.AtlasBitmap, true, true ) )
- info.RecalculateBB( id, dst );
- }
- info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
- }
-
- void HandleCpeRemoveBlockDefinition() {
- if( !game.AllowCustomBlocks ) {
- SkipPacketData( PacketId.CpeRemoveBlockDefinition ); return;
- }
- game.BlockInfo.ResetBlockInfo( reader.ReadUInt8(), true );
- game.BlockInfo.InitLightOffsets();
- game.Events.RaiseBlockDefinitionChanged();
- }
-
- void HandleCpeDefineBlockExt() {
- if( !game.AllowCustomBlocks ) {
- SkipPacketData( PacketId.CpeDefineBlockExt ); return;
- }
- byte id = HandleCpeDefineBlockCommonStart( blockDefinitionsExtVer >= 2 );
- BlockInfo info = game.BlockInfo;
- Vector3 min, max;
-
- min.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.X, 0, 15/16f );
- min.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Y, 0, 15/16f );
- min.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Z, 0, 15/16f );
- max.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.X, 1/16f, 1 );
- max.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Y, 1/16f, 1 );
- max.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Z, 1/16f, 1 );
-
- info.MinBB[id] = min;
- info.MaxBB[id] = max;
- HandleCpeDefineBlockCommonEnd( id );
- info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
- }
-
- byte HandleCpeDefineBlockCommonStart( bool uniqueSideTexs ) {
- byte block = reader.ReadUInt8();
- BlockInfo info = game.BlockInfo;
- info.ResetBlockInfo( block, false );
-
- info.Name[block] = reader.ReadAsciiString();
- info.CollideType[block] = (BlockCollideType)reader.ReadUInt8();
- if( info.CollideType[block] != BlockCollideType.Solid ) {
- info.IsTransparent[block] = true;
- info.IsOpaque[block] = false;
- }
-
- info.SpeedMultiplier[block] = (float)Math.Pow( 2, (reader.ReadUInt8() - 128) / 64f );
- info.SetTex( reader.ReadUInt8(), TileSide.Top, (Block)block );
- if( uniqueSideTexs ) {
- info.SetTex( reader.ReadUInt8(), TileSide.Left, (Block)block );
- info.SetTex( reader.ReadUInt8(), TileSide.Right, (Block)block );
- info.SetTex( reader.ReadUInt8(), TileSide.Front, (Block)block );
- info.SetTex( reader.ReadUInt8(), TileSide.Back, (Block)block );
- } else {
- info.SetSide( reader.ReadUInt8(), (Block)block );
- }
- info.SetTex( reader.ReadUInt8(), TileSide.Bottom, (Block)block );
-
- info.BlocksLight[block] = reader.ReadUInt8() == 0;
- byte sound = reader.ReadUInt8();
- if( sound < breakSnds.Length ) {
- info.StepSounds[block] = stepSnds[sound];
- info.DigSounds[block] = breakSnds[sound];
- }
- info.FullBright[block] = reader.ReadUInt8() != 0;
- return block;
- }
-
- void HandleCpeDefineBlockCommonEnd( byte block ) {
- BlockInfo info = game.BlockInfo;
- byte blockDraw = reader.ReadUInt8();
- SetBlockDraw( info, block, blockDraw );
-
- byte fogDensity = reader.ReadUInt8();
- info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f;
- info.FogColour[block] = new FastColour(
- reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
- info.SetupCullingCache( block );
- info.InitLightOffsets();
- game.Events.RaiseBlockDefinitionChanged();
- }
-
const int bulkCount = 256;
unsafe void HandleBulkBlockUpdate() {
int count = reader.ReadUInt8() + 1;
@@ -498,59 +396,10 @@ namespace ClassicalSharp {
if( code <= ' ' || code > '~' ) return; // Control chars, space, extended chars cannot be used
if( (code >= '0' && code <= '9') || (code >= 'a' && code <= 'f')
|| (code >= 'A' && code <= 'F') ) return; // Standard chars cannot be used.
+ if( code == '%' || code == '&' ) return; // colour code signifiers cannot be used
game.Drawer2D.Colours[code] = col;
game.Events.RaiseColourCodesChanged();
}
-
- void HandleDefineModel() {
- int start = reader.index - 1;
- byte modelId = reader.ReadUInt8();
- switch( reader.ReadUInt8() ) {
- case 0: // setup
- break;
- case 1: // metadata
- break;
- case 2: // define part
- break;
- case 3: // rotation
- break;
- }
- int read = reader.index - start;
- // TODO: skip remaining data
- }
-
- internal static SoundType[] stepSnds, breakSnds;
- static NetworkProcessor() {
- stepSnds = new SoundType[10];
- breakSnds = new SoundType[10];
- stepSnds[0] = SoundType.None; breakSnds[0] = SoundType.None;
- stepSnds[1] = SoundType.Wood; breakSnds[1] = SoundType.Wood;
- stepSnds[2] = SoundType.Gravel; breakSnds[2] = SoundType.Gravel;
- stepSnds[3] = SoundType.Grass; breakSnds[3] = SoundType.Grass;
- stepSnds[4] = SoundType.Stone; breakSnds[4] = SoundType.Stone;
- // TODO: metal sound type, just use stone for now.
- stepSnds[5] = SoundType.Stone; breakSnds[5] = SoundType.Stone;
- stepSnds[6] = SoundType.Stone; breakSnds[6] = SoundType.Glass;
- stepSnds[7] = SoundType.Cloth; breakSnds[7] = SoundType.Cloth;
- stepSnds[8] = SoundType.Sand; breakSnds[8] = SoundType.Sand;
- stepSnds[9] = SoundType.Snow; breakSnds[9] = SoundType.Snow;
- }
-
- internal static void SetBlockDraw( BlockInfo info, byte block, byte blockDraw ) {
- if( blockDraw == 1 ) {
- info.IsTransparent[block] = true;
- } else if( blockDraw == 2 ) {
- info.IsTransparent[block] = true;
- info.CullWithNeighbours[block] = false;
- } else if( blockDraw == 3 ) {
- info.IsTranslucent[block] = true;
- } else if( blockDraw == 4 ) {
- info.IsTransparent[block] = true;
- info.IsAir[block] = true;
- }
- if( info.IsOpaque[block] )
- info.IsOpaque[block] = blockDraw == 0;
- }
}
#endregion
}
\ No newline at end of file
diff --git a/ClassicalSharp/Network/NetworkProcessor.CPECustom.cs b/ClassicalSharp/Network/NetworkProcessor.CPECustom.cs
new file mode 100644
index 000000000..1d753e561
--- /dev/null
+++ b/ClassicalSharp/Network/NetworkProcessor.CPECustom.cs
@@ -0,0 +1,172 @@
+using System;
+using ClassicalSharp.Model;
+using OpenTK;
+
+namespace ClassicalSharp {
+
+ public partial class NetworkProcessor : INetworkProcessor {
+
+ void HandleCpeDefineBlock() {
+ if( !game.AllowCustomBlocks ) {
+ SkipPacketData( PacketId.CpeDefineBlock ); return;
+ }
+ byte id = HandleCpeDefineBlockCommonStart( false );
+ BlockInfo info = game.BlockInfo;
+ byte shape = reader.ReadUInt8();
+ if( shape == 0 ) {
+ info.IsSprite[id] = true;
+ info.IsOpaque[id] = false;
+ info.IsTransparent[id] = true;
+ } else if( shape <= 16 ) {
+ info.MaxBB[id].Y = shape / 16f;
+ }
+
+ HandleCpeDefineBlockCommonEnd( id );
+ // Update sprite BoundingBox if necessary
+ if( info.IsSprite[id] ) {
+ using( FastBitmap dst = new FastBitmap( game.TerrainAtlas.AtlasBitmap, true, true ) )
+ info.RecalculateBB( id, dst );
+ }
+ info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
+ }
+
+ void HandleCpeRemoveBlockDefinition() {
+ if( !game.AllowCustomBlocks ) {
+ SkipPacketData( PacketId.CpeRemoveBlockDefinition ); return;
+ }
+ game.BlockInfo.ResetBlockInfo( reader.ReadUInt8(), true );
+ game.BlockInfo.InitLightOffsets();
+ game.Events.RaiseBlockDefinitionChanged();
+ }
+
+ void HandleCpeDefineBlockExt() {
+ if( !game.AllowCustomBlocks ) {
+ SkipPacketData( PacketId.CpeDefineBlockExt ); return;
+ }
+ byte id = HandleCpeDefineBlockCommonStart( blockDefinitionsExtVer >= 2 );
+ BlockInfo info = game.BlockInfo;
+ Vector3 min, max;
+
+ min.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.X, 0, 15/16f );
+ min.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Y, 0, 15/16f );
+ min.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Z, 0, 15/16f );
+ max.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.X, 1/16f, 1 );
+ max.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Y, 1/16f, 1 );
+ max.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Z, 1/16f, 1 );
+
+ info.MinBB[id] = min;
+ info.MaxBB[id] = max;
+ HandleCpeDefineBlockCommonEnd( id );
+ info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
+ }
+
+ byte HandleCpeDefineBlockCommonStart( bool uniqueSideTexs ) {
+ byte block = reader.ReadUInt8();
+ BlockInfo info = game.BlockInfo;
+ info.ResetBlockInfo( block, false );
+
+ info.Name[block] = reader.ReadAsciiString();
+ info.CollideType[block] = (BlockCollideType)reader.ReadUInt8();
+ if( info.CollideType[block] != BlockCollideType.Solid ) {
+ info.IsTransparent[block] = true;
+ info.IsOpaque[block] = false;
+ }
+
+ info.SpeedMultiplier[block] = (float)Math.Pow( 2, (reader.ReadUInt8() - 128) / 64f );
+ info.SetTex( reader.ReadUInt8(), TileSide.Top, (Block)block );
+ if( uniqueSideTexs ) {
+ info.SetTex( reader.ReadUInt8(), TileSide.Left, (Block)block );
+ info.SetTex( reader.ReadUInt8(), TileSide.Right, (Block)block );
+ info.SetTex( reader.ReadUInt8(), TileSide.Front, (Block)block );
+ info.SetTex( reader.ReadUInt8(), TileSide.Back, (Block)block );
+ } else {
+ info.SetSide( reader.ReadUInt8(), (Block)block );
+ }
+ info.SetTex( reader.ReadUInt8(), TileSide.Bottom, (Block)block );
+
+ info.BlocksLight[block] = reader.ReadUInt8() == 0;
+ byte sound = reader.ReadUInt8();
+ if( sound < breakSnds.Length ) {
+ info.StepSounds[block] = stepSnds[sound];
+ info.DigSounds[block] = breakSnds[sound];
+ }
+ info.FullBright[block] = reader.ReadUInt8() != 0;
+ return block;
+ }
+
+ void HandleCpeDefineBlockCommonEnd( byte block ) {
+ BlockInfo info = game.BlockInfo;
+ byte blockDraw = reader.ReadUInt8();
+ SetBlockDraw( info, block, blockDraw );
+
+ byte fogDensity = reader.ReadUInt8();
+ info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f;
+ info.FogColour[block] = new FastColour(
+ reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
+ info.SetupCullingCache( block );
+ info.InitLightOffsets();
+ game.Events.RaiseBlockDefinitionChanged();
+ }
+
+ void HandleDefineModel() {
+ int start = reader.index - 1;
+ byte id = reader.ReadUInt8();
+ CustomModel model = null;
+
+ switch( reader.ReadUInt8() ) {
+ case 0:
+ model = new CustomModel( game );
+ model.ReadSetupPacket( reader );
+ game.ModelCache.CustomModels[id] = model;
+ break;
+ case 1:
+ model = game.ModelCache.CustomModels[id];
+ if( model != null ) model.ReadMetadataPacket( reader );
+ break;
+ case 2:
+ model = game.ModelCache.CustomModels[id];
+ if( model != null ) model.ReadDefinePartPacket( reader );
+ break;
+ case 3:
+ model = game.ModelCache.CustomModels[id];
+ if( model != null ) model.ReadRotationPacket( reader );
+ break;
+ }
+ int total = packetSizes[(byte)PacketId.CpeDefineModel];
+ reader.Skip( total - (reader.index - start) );
+ }
+
+ internal static SoundType[] stepSnds, breakSnds;
+ static NetworkProcessor() {
+ stepSnds = new SoundType[10];
+ breakSnds = new SoundType[10];
+ stepSnds[0] = SoundType.None; breakSnds[0] = SoundType.None;
+ stepSnds[1] = SoundType.Wood; breakSnds[1] = SoundType.Wood;
+ stepSnds[2] = SoundType.Gravel; breakSnds[2] = SoundType.Gravel;
+ stepSnds[3] = SoundType.Grass; breakSnds[3] = SoundType.Grass;
+ stepSnds[4] = SoundType.Stone; breakSnds[4] = SoundType.Stone;
+ // TODO: metal sound type, just use stone for now.
+ stepSnds[5] = SoundType.Stone; breakSnds[5] = SoundType.Stone;
+ stepSnds[6] = SoundType.Stone; breakSnds[6] = SoundType.Glass;
+ stepSnds[7] = SoundType.Cloth; breakSnds[7] = SoundType.Cloth;
+ stepSnds[8] = SoundType.Sand; breakSnds[8] = SoundType.Sand;
+ stepSnds[9] = SoundType.Snow; breakSnds[9] = SoundType.Snow;
+ }
+
+ internal static void SetBlockDraw( BlockInfo info, byte block, byte blockDraw ) {
+ if( blockDraw == 1 ) {
+ info.IsTransparent[block] = true;
+ } else if( blockDraw == 2 ) {
+ info.IsTransparent[block] = true;
+ info.CullWithNeighbours[block] = false;
+ } else if( blockDraw == 3 ) {
+ info.IsTranslucent[block] = true;
+ } else if( blockDraw == 4 ) {
+ info.IsTransparent[block] = true;
+ info.IsAir[block] = true;
+ }
+ if( info.IsOpaque[block] )
+ info.IsOpaque[block] = blockDraw == 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClassicalSharp/Network/Utils/NetReader.cs b/ClassicalSharp/Network/Utils/NetReader.cs
index bee777994..aeb08ec67 100644
--- a/ClassicalSharp/Network/Utils/NetReader.cs
+++ b/ClassicalSharp/Network/Utils/NetReader.cs
@@ -73,20 +73,22 @@ namespace ClassicalSharp {
public string ReadCp437String() {
int length = GetString( false, 64 );
- index += 64;
return new String( characters, 0, length );
}
public string ReadAsciiString() {
int length = GetString( true, 64 );
- index += 64;
+ return new String( characters, 0, length );
+ }
+
+ public string ReadAsciiString( int maxLength ) {
+ int length = GetString( true, maxLength );
return new String( characters, 0, length );
}
internal string ReadChatString( ref byte messageType, bool useMessageTypes ) {
if( !useMessageTypes ) messageType = (byte)MessageType.Normal;
- int length = GetString( false, 64 );
- index += 64;
+ int length = GetString( false, 64 );
int offset = 0;
if( length >= womDetail.Length && IsWomDetailString() ) {
@@ -107,9 +109,10 @@ namespace ClassicalSharp {
return true;
}
- int GetString( bool ascii, int bufferSize ) {
+ int GetString( bool ascii, int maxLength ) {
int length = 0;
- for( int i = bufferSize - 1; i >= 0; i-- ) {
+
+ for( int i = maxLength - 1; i >= 0; i-- ) {
byte code = buffer[index + i];
if( length == 0 && !( code == 0 || code == 0x20 ) )
length = i + 1;
@@ -128,6 +131,7 @@ namespace ClassicalSharp {
characters[i] = Utils.ExtendedCharReplacements[code - 0x7F];
}
}
+ index += maxLength;
return length;
}
}
diff --git a/ClassicalSharp/SharpWave.dll b/ClassicalSharp/SharpWave.dll
index c567e2cee..eacd96ff1 100644
Binary files a/ClassicalSharp/SharpWave.dll and b/ClassicalSharp/SharpWave.dll differ