mirror of
https://github.com/SteamAutoCracks/DepotDownloaderMod.git
synced 2026-02-11 04:10:56 +01:00
Initial implementation of improved GC message handling.
--HG-- branch : gc
This commit is contained in:
175
SteamKit2/SteamKit2/Base/GC/ClientMsgGC.cs
Normal file
175
SteamKit2/SteamKit2/Base/GC/ClientMsgGC.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'license.txt', which is part of this source code package.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using ProtoBuf;
|
||||
using SteamKit2.Internal.GC;
|
||||
using MsgGCHdrProtoBuf = SteamKit2.Internal.MsgGCHdrProtoBuf;
|
||||
|
||||
namespace SteamKit2.GC
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a protobuf backed client message.
|
||||
/// </summary>
|
||||
/// <typeparam name="BodyType">The body type of this message.</typeparam>
|
||||
public sealed class ClientGCMsgProtobuf<BodyType> : GCMsgBase<MsgGCHdrProtoBuf>
|
||||
where BodyType : IExtensible, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this client message is protobuf backed.
|
||||
/// Client messages of this type are always protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public override bool IsProto { get { return true; } }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The network message type.
|
||||
/// </value>
|
||||
public override uint MsgType { get { return Header.Msg; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The session id.
|
||||
/// </value>
|
||||
public override int SessionID
|
||||
{
|
||||
get { return ProtoHeader.client_session_id; }
|
||||
set { ProtoHeader.client_session_id = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SteamID"/> for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="SteamID"/>.
|
||||
/// </value>
|
||||
public override SteamID SteamID
|
||||
{
|
||||
get { return ProtoHeader.client_steam_id; }
|
||||
set { ProtoHeader.client_steam_id = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
public override ulong TargetJobID
|
||||
{
|
||||
get { return ProtoHeader.job_id_target; }
|
||||
set { ProtoHeader.job_id_target = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the source job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
public override ulong SourceJobID
|
||||
{
|
||||
get { return ProtoHeader.job_id_source; }
|
||||
set { ProtoHeader.job_id_source = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shorthand accessor for the protobuf header.
|
||||
/// </summary>
|
||||
public CMsgProtoBufHeader ProtoHeader { get { return Header.Proto; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the body structure of this message.
|
||||
/// </summary>
|
||||
public BodyType Body { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientMsgProtobuf<BodyType>"/> class.
|
||||
/// This is a client send constructor.
|
||||
/// </summary>
|
||||
/// <param name="eMsg">The network message type this client message represents.</param>
|
||||
/// <param name="payloadReserve">The number of bytes to initialize the payload capacity to.</param>
|
||||
public ClientGCMsgProtobuf( uint eMsg, int payloadReserve = 64 )
|
||||
: base( payloadReserve )
|
||||
{
|
||||
Body = new BodyType();
|
||||
|
||||
// set our emsg
|
||||
Header.Msg = eMsg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientMsgProtobuf<BodyType>"/> class.
|
||||
/// This a reply constructor.
|
||||
/// </summary>
|
||||
/// <param name="eMsg">The network message type this client message represents.</param>
|
||||
/// <param name="msg">The message that this instance is a reply for.</param>
|
||||
/// <param name="payloadReserve">The number of bytes to initialize the payload capacity to.</param>
|
||||
public ClientGCMsgProtobuf( uint eMsg, GCMsgBase<MsgGCHdrProtoBuf> msg, int payloadReserve = 64 )
|
||||
: this( eMsg, payloadReserve )
|
||||
{
|
||||
// our target is where the message came from
|
||||
Header.Proto.job_id_target = msg.Header.Proto.job_id_source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientMsgProtobuf<BodyType>"/> class.
|
||||
/// This is a recieve constructor.
|
||||
/// </summary>
|
||||
/// <param name="msg">The packet message to build this client message from.</param>
|
||||
public ClientGCMsgProtobuf( IPacketGCMsg msg )
|
||||
: this( msg.MsgType )
|
||||
{
|
||||
Deserialize( msg.GetData() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this client message instance to a byte array.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Data representing a client message.
|
||||
/// </returns>
|
||||
public override byte[] Serialize()
|
||||
{
|
||||
using ( MemoryStream ms = new MemoryStream() )
|
||||
{
|
||||
Header.Serialize( ms );
|
||||
Serializer.Serialize( ms, Body );
|
||||
Payload.WriteTo( ms );
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes this client message by deserializing the specified data.
|
||||
/// </summary>
|
||||
/// <param name="data">The data representing a client message.</param>
|
||||
public override void Deserialize( byte[] data )
|
||||
{
|
||||
using ( MemoryStream ms = new MemoryStream( data ) )
|
||||
{
|
||||
Header.Deserialize( ms );
|
||||
Body = Serializer.Deserialize<BodyType>( ms );
|
||||
|
||||
// the rest of the data is the payload
|
||||
int payloadOffset = ( int )ms.Position;
|
||||
int payloadLen = ( int )( ms.Length - ms.Position );
|
||||
|
||||
Payload.Write( data, payloadOffset, payloadLen );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
480
SteamKit2/SteamKit2/Base/GC/MsgBaseGC.cs
Normal file
480
SteamKit2/SteamKit2/Base/GC/MsgBaseGC.cs
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'license.txt', which is part of this source code package.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using SteamKit2.Internal;
|
||||
|
||||
namespace SteamKit2.GC
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a unified interface into client messages.
|
||||
/// </summary>
|
||||
public interface IClientGCMsg
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this client message is protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsProto { get; }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The message type.
|
||||
/// </value>
|
||||
uint MsgType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The session id.
|
||||
/// </value>
|
||||
int SessionID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SteamID"/> for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="SteamID"/>.
|
||||
/// </value>
|
||||
SteamID SteamID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
ulong TargetJobID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the source job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
ulong SourceJobID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this client message instance to a byte array.
|
||||
/// </summary>
|
||||
/// <returns>Data representing a client message.</returns>
|
||||
byte[] Serialize();
|
||||
/// <summary>
|
||||
/// Initializes this client message by deserializing the specified data.
|
||||
/// </summary>
|
||||
/// <param name="data">The data representing a client message.</param>
|
||||
void Deserialize( byte[] data );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the abstract base class for all available client messages.
|
||||
/// It's used to maintain packet payloads and provide a header for all client messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="HdrType">The header type for this client message.</typeparam>
|
||||
public abstract class GCMsgBase<HdrType> : IClientGCMsg
|
||||
where HdrType : IGCSerializableHeader, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this client message is protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public abstract bool IsProto { get; }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The network message type.
|
||||
/// </value>
|
||||
public abstract uint MsgType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The session id.
|
||||
/// </value>
|
||||
public abstract int SessionID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SteamID"/> for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="SteamID"/>.
|
||||
/// </value>
|
||||
public abstract SteamID SteamID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
public abstract ulong TargetJobID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the source job id for this client message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
public abstract ulong SourceJobID { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the header for this message type.
|
||||
/// </summary>
|
||||
public HdrType Header { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.IO.MemoryStream"/> which is the backing stream for client message payload data.
|
||||
/// </summary>
|
||||
public MemoryStream Payload { get; private set; }
|
||||
|
||||
|
||||
BinaryReader reader;
|
||||
BinaryWriter writer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MsgBase<HdrType>"/> class.
|
||||
/// </summary>
|
||||
/// <param name="payloadReserve">The number of bytes to initialize the payload capacity to.</param>
|
||||
public GCMsgBase( int payloadReserve = 0 )
|
||||
{
|
||||
Header = new HdrType();
|
||||
|
||||
Payload = new MemoryStream( payloadReserve );
|
||||
reader = new BinaryReader( Payload );
|
||||
writer = new BinaryWriter( Payload );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this client message instance to a byte array.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Data representing a client message.
|
||||
/// </returns>
|
||||
public abstract byte[] Serialize();
|
||||
/// <summary>
|
||||
/// Initializes this client message by deserializing the specified data.
|
||||
/// </summary>
|
||||
/// <param name="data">The data representing a client message.</param>
|
||||
public abstract void Deserialize( byte[] data );
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Seeks within the payload to the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset in the payload to seek to.</param>
|
||||
/// <param name="loc">The origin to seek from.</param>
|
||||
/// <returns>The new position within the stream, calculated by combining the initial reference point and the offset.</returns>
|
||||
public long Seek( long offset, SeekOrigin loc )
|
||||
{
|
||||
return Payload.Seek( offset, loc );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a single unsigned byte to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The unsigned byte.</param>
|
||||
public void Write( byte data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single signed byte to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The signed byte.</param>
|
||||
public void Write( sbyte data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the specified byte array to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The byte array.</param>
|
||||
public void Write( byte[] data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single 16bit short to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The short.</param>
|
||||
public void Write( short data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single unsigned 16bit short to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The unsigned short.</param>
|
||||
public void Write( ushort data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single 32bit integer to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The integer.</param>
|
||||
public void Write( int data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single unsigned 32bit integer to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The unsigned integer.</param>
|
||||
public void Write( uint data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single 64bit long to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The long.</param>
|
||||
public void Write( long data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single unsigned 64bit long to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The unsigned long.</param>
|
||||
public void Write( ulong data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single 32bit float to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The float.</param>
|
||||
public void Write( float data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a single 64bit double to the message payload.
|
||||
/// </summary>
|
||||
/// <param name="data">The double.</param>
|
||||
public void Write( double data )
|
||||
{
|
||||
writer.Write( data );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified string to the message payload using default encoding.
|
||||
/// This function does not write a terminating null character.
|
||||
/// </summary>
|
||||
/// <param name="data">The string to write.</param>
|
||||
public void Write( string data )
|
||||
{
|
||||
Write( data, Encoding.Default );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the specified string to the message payload using the specified encoding.
|
||||
/// This function does not write a terminating null character.
|
||||
/// </summary>
|
||||
/// <param name="data">The string to write.</param>
|
||||
/// <param name="encoding">The encoding to use.</param>
|
||||
public void Write( string data, Encoding encoding )
|
||||
{
|
||||
if ( data == null )
|
||||
return;
|
||||
|
||||
Write( encoding.GetBytes( data ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the secified string and a null terminator to the message payload using default encoding.
|
||||
/// </summary>
|
||||
/// <param name="data">The string to write.</param>
|
||||
public void WriteNullTermString( string data )
|
||||
{
|
||||
WriteNullTermString( data, Encoding.Default );
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the specified string and a null terminator to the message payload using the specified encoding.
|
||||
/// </summary>
|
||||
/// <param name="data">The string to write.</param>
|
||||
/// <param name="encoding">The encoding to use.</param>
|
||||
public void WriteNullTermString( string data, Encoding encoding )
|
||||
{
|
||||
Write( data, encoding );
|
||||
Write( encoding.GetBytes( "\0" ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a single signed byte from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The signed byte.</returns>
|
||||
public sbyte ReadInt8()
|
||||
{
|
||||
return reader.ReadSByte();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single signed byte from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The signed byte.</returns>
|
||||
public sbyte ReadSByte()
|
||||
{
|
||||
return reader.ReadSByte();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned byte from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned byte.</returns>
|
||||
public byte ReadUInt8()
|
||||
{
|
||||
return reader.ReadByte();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned byte from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned byte.</returns>
|
||||
public byte ReadByte()
|
||||
{
|
||||
return reader.ReadByte();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a number of bytes from the message payload.
|
||||
/// </summary>
|
||||
/// <param name="numBytes">The number of bytes to read.</param>
|
||||
/// <returns>The data.</returns>
|
||||
public byte[] ReadBytes( int numBytes )
|
||||
{
|
||||
return reader.ReadBytes( numBytes );
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 16bit short from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The short.</returns>
|
||||
public short ReadInt16()
|
||||
{
|
||||
return reader.ReadInt16();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 16bit short from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The short.</returns>
|
||||
public short ReadShort()
|
||||
{
|
||||
return reader.ReadInt16();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 16bit short from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned short.</returns>
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
return reader.ReadUInt16();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 16bit short from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned short.</returns>
|
||||
public ushort ReadUShort()
|
||||
{
|
||||
return reader.ReadUInt16();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 32bit integer from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The integer.</returns>
|
||||
public int ReadInt32()
|
||||
{
|
||||
return reader.ReadInt32();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 32bit integer from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The integer.</returns>
|
||||
public int ReadInt()
|
||||
{
|
||||
return reader.ReadInt32();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 32bit integer from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned integer.</returns>
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
return reader.ReadUInt32();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 32bit integer from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned integer.</returns>
|
||||
public uint ReadUInt()
|
||||
{
|
||||
return reader.ReadUInt32();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 64bit long from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The long.</returns>
|
||||
public long ReadInt64()
|
||||
{
|
||||
return reader.ReadInt64();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 64bit long from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The long.</returns>
|
||||
public long ReadLong()
|
||||
{
|
||||
return reader.ReadInt64();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 64bit long from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned long.</returns>
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
return reader.ReadUInt64();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single unsigned 64bit long from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned long.</returns>
|
||||
public ulong ReadULong()
|
||||
{
|
||||
return reader.ReadUInt64();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 32bit float from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The float.</returns>
|
||||
public float ReadSingle()
|
||||
{
|
||||
return reader.ReadSingle();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 32bit float from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The float.</returns>
|
||||
public float ReadFloat()
|
||||
{
|
||||
return reader.ReadSingle();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a single 64bit double from the message payload.
|
||||
/// </summary>
|
||||
/// <returns>The double.</returns>
|
||||
public double ReadDouble()
|
||||
{
|
||||
return reader.ReadDouble();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
206
SteamKit2/SteamKit2/Base/GC/PacketBaseGC.cs
Normal file
206
SteamKit2/SteamKit2/Base/GC/PacketBaseGC.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'license.txt', which is part of this source code package.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using SteamKit2.Internal;
|
||||
|
||||
namespace SteamKit2.GC
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple unified interface into client messages recieved from the network.
|
||||
/// This is contrasted with <see cref="IClientMsg"/> in that this interface is packet body agnostic
|
||||
/// and only allows simple access into the header. This interface is also immutable, and the underlying
|
||||
/// data cannot be modified.
|
||||
/// </summary>
|
||||
public interface IPacketGCMsg
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this packet message is protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsProto { get; }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The message type.
|
||||
/// </value>
|
||||
uint MsgType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
ulong TargetJobID { get; }
|
||||
/// <summary>
|
||||
/// Gets the source job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
ulong SourceJobID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying data that represents this client message.
|
||||
/// </summary>
|
||||
/// <returns>The data.</returns>
|
||||
byte[] GetData();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a protobuf backed packet message.
|
||||
/// </summary>
|
||||
public sealed class PacketClientGCMsgProtobuf : IPacketGCMsg
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this packet message is protobuf backed.
|
||||
/// This type of message is always protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsProto { get { return true; } }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The message type.
|
||||
/// </value>
|
||||
public uint MsgType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
public ulong TargetJobID { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the source job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
public ulong SourceJobID { get; private set; }
|
||||
|
||||
|
||||
byte[] payload;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PacketClientMsgProtobuf"/> class.
|
||||
/// </summary>
|
||||
/// <param name="eMsg">The network message type for this packet message.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
public PacketClientGCMsgProtobuf( uint eMsg, byte[] data )
|
||||
{
|
||||
MsgType = eMsg;
|
||||
payload = data;
|
||||
|
||||
MsgGCHdrProtoBuf protobufHeader = new MsgGCHdrProtoBuf();
|
||||
|
||||
// we need to pull out the job ids, so we deserialize the protobuf header
|
||||
using ( MemoryStream ms = new MemoryStream( data ) )
|
||||
{
|
||||
protobufHeader.Deserialize( ms );
|
||||
}
|
||||
|
||||
TargetJobID = protobufHeader.Proto.job_id_target;
|
||||
SourceJobID = protobufHeader.Proto.job_id_source;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying data that represents this client message.
|
||||
/// </summary>
|
||||
/// <returns>The data.</returns>
|
||||
public byte[] GetData()
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a packet message with extended header information.
|
||||
/// </summary>
|
||||
public sealed class PacketClientGCMsg : IPacketGCMsg
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this packet message is protobuf backed.
|
||||
/// This type of message is never protobuf backed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is protobuf backed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsProto { get { return false; } }
|
||||
/// <summary>
|
||||
/// Gets the network message type of this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The message type.
|
||||
/// </value>
|
||||
public uint MsgType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target job id.
|
||||
/// </value>
|
||||
public ulong TargetJobID { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the source job id for this packet message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The source job id.
|
||||
/// </value>
|
||||
public ulong SourceJobID { get; private set; }
|
||||
|
||||
byte[] payload;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PacketClientMsg"/> class.
|
||||
/// </summary>
|
||||
/// <param name="eMsg">The network message type for this packet message.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
public PacketClientGCMsg( uint eMsg, byte[] data )
|
||||
{
|
||||
MsgType = eMsg;
|
||||
payload = data;
|
||||
|
||||
MsgGCHdr gcHdr = new MsgGCHdr();
|
||||
|
||||
// deserialize the gc header to get our hands on the job ids
|
||||
using ( MemoryStream ms = new MemoryStream( data ) )
|
||||
{
|
||||
gcHdr.Deserialize( ms );
|
||||
}
|
||||
|
||||
TargetJobID = gcHdr.TargetJobID;
|
||||
SourceJobID = gcHdr.SourceJobID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying data that represents this client message.
|
||||
/// </summary>
|
||||
/// <returns>The data.</returns>
|
||||
public byte[] GetData()
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamKit2.Internal;
|
||||
using SteamKit2.GC;
|
||||
|
||||
namespace SteamKit2
|
||||
{
|
||||
@@ -13,7 +14,9 @@ namespace SteamKit2
|
||||
/// </summary>
|
||||
public class MessageCallback : CallbackMsg
|
||||
{
|
||||
// raw emsg (with protobuf flag, if present)
|
||||
uint eMsg;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the game coordinator message type.
|
||||
/// </summary>
|
||||
@@ -33,7 +36,7 @@ namespace SteamKit2
|
||||
/// <summary>
|
||||
/// Gets the actual message.
|
||||
/// </summary>
|
||||
public byte[] Payload { get; private set; }
|
||||
public IPacketGCMsg Message { get; private set; }
|
||||
|
||||
|
||||
#if STATIC_CALLBACKS
|
||||
@@ -46,7 +49,23 @@ namespace SteamKit2
|
||||
this.eMsg = gcMsg.msgtype;
|
||||
this.AppID = gcMsg.appid;
|
||||
|
||||
this.Payload = gcMsg.payload;
|
||||
this.Message = GetPacketGCMsg( gcMsg.msgtype, gcMsg.payload );
|
||||
}
|
||||
|
||||
|
||||
static IPacketGCMsg GetPacketGCMsg( uint eMsg, byte[] data )
|
||||
{
|
||||
// strip off the protobuf flag
|
||||
uint realEMsg = MsgUtil.GetGCMsg( eMsg );
|
||||
|
||||
if ( MsgUtil.IsProtoBuf( eMsg ) )
|
||||
{
|
||||
return new PacketClientGCMsgProtobuf( realEMsg, data );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new PacketClientGCMsg( realEMsg, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,20 +13,19 @@ namespace SteamKit2
|
||||
public sealed partial class SteamGameCoordinator : ClientMsgHandler
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends a game coordinator message for a specific appid.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to send. This should be a serialized GC message.</param>
|
||||
/// <param name="msg">The GC message to send.</param>
|
||||
/// <param name="appId">The app id of the game coordinator to send to.</param>
|
||||
public void Send( byte[] data, uint appId )
|
||||
public void Send( IClientGCMsg msg, uint appId )
|
||||
{
|
||||
var clientMsg = new ClientMsgProtobuf<CMsgGCClient>( EMsg.ClientToGC );
|
||||
|
||||
clientMsg.Body.msgtype = BitConverter.ToUInt32( data, 0 );
|
||||
clientMsg.Body.msgtype = msg.MsgType;
|
||||
clientMsg.Body.appid = appId;
|
||||
|
||||
clientMsg.Body.payload = data;
|
||||
clientMsg.Body.payload = msg.Serialize();
|
||||
|
||||
this.Client.Send( clientMsg );
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace SteamKit2
|
||||
if ( mgr != null )
|
||||
mgr.Unregister( this );
|
||||
|
||||
GC.SuppressFinalize( this );
|
||||
System.GC.SuppressFinalize( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Base\ClientMsg.cs" />
|
||||
<Compile Include="Base\GC\MsgBaseGC.cs" />
|
||||
<Compile Include="Base\GC\ClientMsgGC.cs" />
|
||||
<Compile Include="Base\GC\PacketBaseGC.cs" />
|
||||
<Compile Include="Base\Generated\ContentManifest.cs" />
|
||||
<Compile Include="Base\Generated\GC\SteamMsgBase.cs" />
|
||||
<Compile Include="Base\Generated\GC\SteamMsgGC.cs" />
|
||||
|
||||
Reference in New Issue
Block a user