## Breaking Changes
Incoming packet registration signature has changed to:
```cs
delegate* void OnReceiveCallback(NetState state, SpanReader reader, int packetLength);
IncomingPackets.Register(int packetID, int length, bool ingame, OnReceiveCallback onReceive);
```
For example, an incoming packet handler signature would now look like this:
```cs
public static void SomeIncomingPacket(NetState state, SpanReader reader, int packetLength)
{
// Parse the data
}
```
## Summary
Updates the network Pipe class to use a mirrored memory technique. This technique involves mapping the same physical memory to two contiguous virtual memory spaces so the byte buffer appears duplicated. This allows writing to a double-sized array to wrap around without the need for the `CircularBuffer` classes.
In practice this allows us to use `Span<byte>` as if the buffer was a regular array.
### Bug Fixes
- [X] Fixes bad fixed length string parsing
182 lines
6.3 KiB
C#
182 lines
6.3 KiB
C#
using System;
|
|
using System.Buffers;
|
|
using Server.Accounting;
|
|
using Server.Commands;
|
|
using Server.Gumps;
|
|
using Server.Network;
|
|
using Server.Targeting;
|
|
|
|
namespace Server
|
|
{
|
|
public class HardwareInfo
|
|
{
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int CpuModel { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int CpuClockSpeed { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int CpuQuantity { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int OSMajor { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int OSMinor { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int OSRevision { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int InstanceID { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int ScreenWidth { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int ScreenHeight { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int ScreenDepth { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int PhysicalMemory { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int CpuManufacturer { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int CpuFamily { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int VCVendorID { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int VCDeviceID { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int VCMemory { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int DXMajor { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int DXMinor { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public string VCDescription { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public string Language { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int Distribution { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int ClientsRunning { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int ClientsInstalled { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int PartialInstalled { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public string Unknown { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public DateTime TimeReceived { get; private set; }
|
|
|
|
public static unsafe void Configure()
|
|
{
|
|
IncomingPackets.Register(0xD9, 0x10C, false, &OnReceive);
|
|
|
|
CommandSystem.Register("HWInfo", AccessLevel.GameMaster, HWInfo_OnCommand);
|
|
}
|
|
|
|
[Usage("HWInfo"), Description("Displays information about a targeted player's hardware.")]
|
|
public static void HWInfo_OnCommand(CommandEventArgs e)
|
|
{
|
|
e.Mobile.BeginTarget(-1, false, TargetFlags.None, HWInfo_OnTarget);
|
|
e.Mobile.SendMessage("Target a player to view their hardware information.");
|
|
}
|
|
|
|
public static void HWInfo_OnTarget(Mobile from, object obj)
|
|
{
|
|
if (obj is Mobile m && m.Player)
|
|
{
|
|
if (m.Account is Account acct)
|
|
{
|
|
var hwInfo = acct.HardwareInfo;
|
|
|
|
if (hwInfo != null)
|
|
{
|
|
CommandLogging.WriteLine(
|
|
from,
|
|
$"{from.AccessLevel} {CommandLogging.Format(from)} viewing hardware info of {CommandLogging.Format(m)}"
|
|
);
|
|
}
|
|
|
|
if (hwInfo != null)
|
|
{
|
|
from.SendGump(new PropertiesGump(from, hwInfo));
|
|
}
|
|
else
|
|
{
|
|
from.SendMessage("No hardware information for that account was found.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
from.SendMessage("No account has been attached to that player.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
from.BeginTarget(-1, false, TargetFlags.None, HWInfo_OnTarget);
|
|
from.SendMessage("That is not a player. Try again.");
|
|
}
|
|
}
|
|
|
|
public static void OnReceive(NetState state, SpanReader reader, int packetLength)
|
|
{
|
|
reader.ReadByte(); // 1: <4.0.1a, 2>=4.0.1a
|
|
|
|
var info = new HardwareInfo
|
|
{
|
|
InstanceID = reader.ReadInt32(),
|
|
OSMajor = reader.ReadInt32(),
|
|
OSMinor = reader.ReadInt32(),
|
|
OSRevision = reader.ReadInt32(),
|
|
CpuManufacturer = reader.ReadByte(),
|
|
CpuFamily = reader.ReadInt32(),
|
|
CpuModel = reader.ReadInt32(),
|
|
CpuClockSpeed = reader.ReadInt32(),
|
|
CpuQuantity = reader.ReadByte(),
|
|
PhysicalMemory = reader.ReadInt32(),
|
|
ScreenWidth = reader.ReadInt32(),
|
|
ScreenHeight = reader.ReadInt32(),
|
|
ScreenDepth = reader.ReadInt32(),
|
|
DXMajor = reader.ReadInt16(),
|
|
DXMinor = reader.ReadInt16(),
|
|
VCDescription = reader.ReadLittleUniSafe(64),
|
|
VCVendorID = reader.ReadInt32(),
|
|
VCDeviceID = reader.ReadInt32(),
|
|
VCMemory = reader.ReadInt32(),
|
|
Distribution = reader.ReadByte(),
|
|
ClientsRunning = reader.ReadByte(),
|
|
ClientsInstalled = reader.ReadByte(),
|
|
PartialInstalled = reader.ReadByte(),
|
|
Language = reader.ReadLittleUniSafe(4),
|
|
Unknown = reader.ReadAsciiSafe(64),
|
|
TimeReceived = Core.Now
|
|
};
|
|
|
|
if (state.Account is Account acct)
|
|
{
|
|
acct.HardwareInfo = info;
|
|
}
|
|
}
|
|
}
|
|
}
|