Fixes bugs in world save (#297)
- [X] Fixes bugs in the buffer writer
- [X] Removes background save commands
- [X] Avoids calling Serialize() on deserialization
- In a future optimization I will copy the entire object to a buffer, deserialize using a SpanReader, then use that buffer for the SaveBuffer
- [X] Fixes issue with decay queue.
Bumps release version
This commit is contained in:
parent
daf48ebdf2
commit
55935d30b4
12 changed files with 122 additions and 153 deletions
|
|
@ -145,22 +145,17 @@ namespace Server
|
|||
{
|
||||
var count = ReadInt();
|
||||
|
||||
if (count > 0)
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
if (ReadItem() is T item)
|
||||
{
|
||||
if (ReadItem() is T item)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return new List<T>();
|
||||
return list;
|
||||
}
|
||||
|
||||
public HashSet<Item> ReadItemSet() => ReadItemSet<Item>();
|
||||
|
|
@ -169,22 +164,17 @@ namespace Server
|
|||
{
|
||||
var count = ReadInt();
|
||||
|
||||
if (count > 0)
|
||||
var set = new HashSet<T>();
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var set = new HashSet<T>();
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
if (ReadItem() is T item)
|
||||
{
|
||||
if (ReadItem() is T item)
|
||||
{
|
||||
set.Add(item);
|
||||
}
|
||||
set.Add(item);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
return new HashSet<T>();
|
||||
return set;
|
||||
}
|
||||
|
||||
public List<Mobile> ReadStrongMobileList() => ReadStrongMobileList<Mobile>();
|
||||
|
|
@ -193,22 +183,17 @@ namespace Server
|
|||
{
|
||||
var count = ReadInt();
|
||||
|
||||
if (count > 0)
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
if (ReadMobile() is T m)
|
||||
{
|
||||
if (ReadMobile() is T m)
|
||||
{
|
||||
list.Add(m);
|
||||
}
|
||||
list.Add(m);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return new List<T>();
|
||||
return list;
|
||||
}
|
||||
|
||||
public HashSet<Mobile> ReadMobileSet() => ReadMobileSet<Mobile>();
|
||||
|
|
@ -216,23 +201,17 @@ namespace Server
|
|||
public HashSet<T> ReadMobileSet<T>() where T : Mobile
|
||||
{
|
||||
var count = ReadInt();
|
||||
var set = new HashSet<T>();
|
||||
|
||||
if (count > 0)
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var set = new HashSet<T>();
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
if (ReadMobile() is T item)
|
||||
{
|
||||
if (ReadMobile() is T item)
|
||||
{
|
||||
set.Add(item);
|
||||
}
|
||||
set.Add(item);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
return new HashSet<T>();
|
||||
return set;
|
||||
}
|
||||
|
||||
public List<BaseGuild> ReadStrongGuildList() => ReadStrongGuildList<BaseGuild>();
|
||||
|
|
@ -240,11 +219,10 @@ namespace Server
|
|||
public List<T> ReadStrongGuildList<T>() where T : BaseGuild
|
||||
{
|
||||
var count = ReadInt();
|
||||
var list = new List<T>(count);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
if (ReadGuild() is T g)
|
||||
|
|
@ -252,11 +230,9 @@ namespace Server
|
|||
list.Add(g);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return new List<T>();
|
||||
return list;
|
||||
}
|
||||
|
||||
public HashSet<BaseGuild> ReadGuildSet() => ReadGuildSet<BaseGuild>();
|
||||
|
|
@ -265,10 +241,10 @@ namespace Server
|
|||
{
|
||||
var count = ReadInt();
|
||||
|
||||
var set = new HashSet<T>();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
var set = new HashSet<T>();
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
if (ReadGuild() is T item)
|
||||
|
|
@ -276,17 +252,17 @@ namespace Server
|
|||
set.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
return new HashSet<T>();
|
||||
return set;
|
||||
}
|
||||
|
||||
public Race ReadRace() => Race.Races[ReadByte()];
|
||||
|
||||
public bool End() => m_File.PeekChar() == -1;
|
||||
|
||||
public int Read(Span<byte> buffer) => m_File.Read(buffer);
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_File.Close();
|
||||
|
|
|
|||
|
|
@ -20,11 +20,18 @@ namespace Server
|
|||
public class BinaryFileWriter : BufferWriter
|
||||
{
|
||||
private readonly Stream m_File;
|
||||
private long m_Position;
|
||||
|
||||
public BinaryFileWriter(string filename, bool prefixStr) : base(prefixStr) =>
|
||||
m_File = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
public BinaryFileWriter(Stream stream, bool prefixStr) : base(prefixStr) => m_File = stream;
|
||||
public BinaryFileWriter(Stream stream, bool prefixStr) : base(prefixStr)
|
||||
{
|
||||
m_File = stream;
|
||||
m_Position = m_File.Position;
|
||||
}
|
||||
|
||||
public override long Position => m_Position + m_Index;
|
||||
|
||||
|
||||
protected override int BufferSize => 512;
|
||||
|
|
@ -35,21 +42,24 @@ namespace Server
|
|||
{
|
||||
m_Position += m_Index;
|
||||
|
||||
m_File.Write(m_Buffer, 0, m_Index);
|
||||
m_File.Write(m_Buffer, 0, (int)m_Index);
|
||||
m_Index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
if (m_Index > 0)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
m_File.Close();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
m_Position += m_Index;
|
||||
m_Index = 0;
|
||||
Flush();
|
||||
|
||||
return m_Position = m_File.Seek(offset, origin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ namespace Server
|
|||
private readonly bool m_PrefixStrings;
|
||||
|
||||
protected byte[] m_Buffer;
|
||||
protected int m_Index;
|
||||
protected long m_Position;
|
||||
protected long m_Index;
|
||||
|
||||
private readonly char[] m_SingleCharBuffer = new char[1];
|
||||
|
||||
|
|
@ -40,6 +39,13 @@ namespace Server
|
|||
|
||||
private int m_MaxBufferChars;
|
||||
|
||||
public BufferWriter(byte[] buffer, bool prefixStr)
|
||||
{
|
||||
m_PrefixStrings = prefixStr;
|
||||
m_Encoding = Utility.UTF8;
|
||||
m_Buffer = buffer;
|
||||
}
|
||||
|
||||
public BufferWriter(bool prefixStr)
|
||||
{
|
||||
m_PrefixStrings = prefixStr;
|
||||
|
|
@ -47,29 +53,23 @@ namespace Server
|
|||
m_Buffer = new byte[BufferSize];
|
||||
}
|
||||
|
||||
public virtual long Position => m_Index;
|
||||
|
||||
protected virtual int BufferSize => 256;
|
||||
|
||||
public byte[] Data => m_Buffer;
|
||||
|
||||
public long Position
|
||||
{
|
||||
get => m_Position + m_Index;
|
||||
set => Seek(value, value < 0 ? SeekOrigin.End : SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
if (m_Index > 0)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Resize(int size)
|
||||
{
|
||||
Array.Resize(ref m_Buffer, size);
|
||||
var copy = new byte[size];
|
||||
Buffer.BlockCopy(m_Buffer, 0, copy, 0, Math.Min(size, m_Buffer.Length));
|
||||
m_Buffer = copy;
|
||||
}
|
||||
|
||||
public virtual void Flush()
|
||||
|
|
@ -77,16 +77,19 @@ namespace Server
|
|||
Resize(m_Buffer.Length * 2);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_Index = 0;
|
||||
}
|
||||
|
||||
public virtual long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
Flush();
|
||||
|
||||
return origin switch
|
||||
{
|
||||
SeekOrigin.Begin => m_Position = offset,
|
||||
SeekOrigin.Current => m_Position += offset,
|
||||
SeekOrigin.End => m_Position = BufferSize - offset,
|
||||
_ => m_Position
|
||||
SeekOrigin.Begin => m_Index = offset,
|
||||
SeekOrigin.Current => m_Index += offset,
|
||||
SeekOrigin.End => m_Index = BufferSize - offset,
|
||||
_ => m_Index
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +324,7 @@ namespace Server
|
|||
|
||||
m_SingleCharBuffer[0] = value;
|
||||
|
||||
var byteCount = m_Encoding.GetBytes(m_SingleCharBuffer, 0, 1, m_Buffer, m_Index);
|
||||
var byteCount = m_Encoding.GetBytes(m_SingleCharBuffer, 0, 1, m_Buffer, (int)m_Index);
|
||||
m_Index += byteCount;
|
||||
}
|
||||
|
||||
|
|
@ -337,13 +340,13 @@ namespace Server
|
|||
|
||||
public void Write(byte[] value, int length)
|
||||
{
|
||||
int remaining = length;
|
||||
int idx = 0;
|
||||
var remaining = length;
|
||||
var idx = 0;
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
int size = Math.Min(m_Buffer.Length - m_Index, remaining);
|
||||
Buffer.BlockCopy(value, idx, m_Buffer, m_Index, size);
|
||||
int size = Math.Min(m_Buffer.Length - (int)m_Index, remaining);
|
||||
Buffer.BlockCopy(value, idx, m_Buffer, (int)m_Index, size);
|
||||
// value.Slice(idx).CopyTo(m_Buffer.AsSpan(m_Index, size));
|
||||
|
||||
remaining -= size;
|
||||
|
|
@ -775,7 +778,7 @@ namespace Server
|
|||
Flush();
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(m_CharacterBuffer, 0, m_Buffer, m_Index, byteLength);
|
||||
Buffer.BlockCopy(m_CharacterBuffer, 0, m_Buffer, (int)m_Index, byteLength);
|
||||
m_Index += byteLength;
|
||||
|
||||
current += charCount;
|
||||
|
|
@ -791,7 +794,7 @@ namespace Server
|
|||
Flush();
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(m_CharacterBuffer, 0, m_Buffer, m_Index, byteLength);
|
||||
Buffer.BlockCopy(m_CharacterBuffer, 0, m_Buffer, (int)m_Index, byteLength);
|
||||
m_Index += byteLength;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,5 +68,6 @@ namespace Server
|
|||
HashSet<T> ReadGuildSet<T>() where T : BaseGuild;
|
||||
Race ReadRace();
|
||||
bool End();
|
||||
int Read(Span<byte> buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public interface ISerializable
|
||||
|
|
@ -22,7 +20,7 @@ namespace Server
|
|||
BufferWriter SaveBuffer { get; set; }
|
||||
int TypeRef { get; }
|
||||
Serial Serial { get; }
|
||||
void Serialize(DateTime serializeStart);
|
||||
void Serialize();
|
||||
void Deserialize(IGenericReader reader);
|
||||
void Serialize(IGenericWriter writer);
|
||||
void Delete();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue