Skip to content

Commit

Permalink
Add support for Underlords GC messages (#697)
Browse files Browse the repository at this point in the history
* Update Protobufs submodule to pull in Underlords protos.

* Generate Underlords proto classes.

* Add Underlords specializations to NHA2.

* Add GC ConnectionStatus msg type overrides to other games.

* Add missing NHA2 project change for added Underlords specialization files.
  • Loading branch information
psychonic authored Jun 23, 2019
1 parent ed616f8 commit 361b0d5
Show file tree
Hide file tree
Showing 21 changed files with 31,318 additions and 4 deletions.
13 changes: 12 additions & 1 deletion Resources/NetHookAnalyzer2/NetHookAnalyzer2/EMsgExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using CSGO = SteamKit2.GC.CSGO.Internal;
using Dota = SteamKit2.GC.Dota.Internal;
using TF2 = SteamKit2.GC.TF2.Internal;
using Underlords = SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2
{
Expand Down Expand Up @@ -66,7 +67,17 @@ static IEnumerable<Type> GetGCEMsgEnums(uint appId)
yield return typeof(Artifact.EGCDCGCommonMessages);
yield return typeof(Artifact.EGCDCGServerMessages);
break;
}

case WellKnownAppIDs.Underlords:
yield return typeof( Underlords.EGCBaseMsg );
yield return typeof( Underlords.ESOMsg );
yield return typeof( Underlords.EGCItemMsg );
yield return typeof( Underlords.EGCBaseClientMsg );
yield return typeof( Underlords.EGCDACClientMessages );
yield return typeof( Underlords.EGCDACCommonMessages );
yield return typeof( Underlords.EGCDACServerMessages );
break;
}
}
}
}
3 changes: 3 additions & 0 deletions Resources/NetHookAnalyzer2/NetHookAnalyzer2/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ static ISpecialization[] LoadMessageObjectSpecializations()
new ArtifactCacheSubscribedGCSpecialization(),
new ArtifactSOMultipleObjectsGCSpecialization(),
new ArtifactSOSingleObjectGCSpecialization(),
new UnderlordsCacheSubscribedGCSpecialization(),
new UnderlordsSOMultipleObjectsGCSpecialization(),
new UnderlordsSOSingleObjectGCSpecialization(),
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ static IEnumerable<string> GetPossibleGCTypePrefixes(uint appid)

case WellKnownAppIDs.Artifact:
yield return "SteamKit2.GC.Artifact.Internal.CMsg";
break;
}
break;

case WellKnownAppIDs.Underlords:
yield return "SteamKit2.GC.Underlords.Internal.CMsg";
break;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Dota = SteamKit2.GC.Dota.Internal;
using TF2 = SteamKit2.GC.TF2.Internal;
using Artifact = SteamKit2.GC.Artifact.Internal;
using Underlords = SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2
{
Expand Down Expand Up @@ -53,6 +54,8 @@ static class MessageTypeOverrides
[(uint)Dota.EGCBaseClientMsg.k_EMsgGCClientWelcome] = typeof(Dota.CMsgClientWelcome),
[(uint)Dota.EGCBaseClientMsg.k_EMsgGCServerHello] = typeof(Dota.CMsgClientHello),
[(uint)Dota.EGCBaseClientMsg.k_EMsgGCServerWelcome] = typeof(Dota.CMsgClientWelcome),
[(uint)Dota.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = typeof(Dota.CMsgConnectionStatus),
[(uint)Dota.EGCBaseClientMsg.k_EMsgGCServerConnectionStatus] = typeof(Dota.CMsgConnectionStatus),

[(uint)Dota.ESOMsg.k_ESOMsg_Create] = typeof(Dota.CMsgSOSingleObject),
[(uint)Dota.ESOMsg.k_ESOMsg_Destroy] = typeof(Dota.CMsgSOSingleObject),
Expand All @@ -68,6 +71,8 @@ static class MessageTypeOverrides
[(uint)CSGO.EGCBaseClientMsg.k_EMsgGCClientWelcome] = typeof(CSGO.CMsgClientWelcome),
[(uint)CSGO.EGCBaseClientMsg.k_EMsgGCServerHello] = typeof(CSGO.CMsgClientHello),
[(uint)CSGO.EGCBaseClientMsg.k_EMsgGCServerWelcome] = typeof(CSGO.CMsgClientWelcome),
[(uint)CSGO.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = typeof(CSGO.CMsgConnectionStatus),
[(uint)CSGO.EGCBaseClientMsg.k_EMsgGCServerConnectionStatus] = typeof(CSGO.CMsgConnectionStatus),

[(uint)CSGO.ESOMsg.k_ESOMsg_Create] = typeof(CSGO.CMsgSOSingleObject),
[(uint)CSGO.ESOMsg.k_ESOMsg_Destroy] = typeof(CSGO.CMsgSOSingleObject),
Expand All @@ -80,12 +85,28 @@ static class MessageTypeOverrides
[(uint)Artifact.EGCBaseClientMsg.k_EMsgGCClientWelcome] = typeof(Artifact.CMsgClientWelcome),
[(uint)Artifact.EGCBaseClientMsg.k_EMsgGCServerHello] = typeof(Artifact.CMsgClientHello),
[(uint)Artifact.EGCBaseClientMsg.k_EMsgGCServerWelcome] = typeof(Artifact.CMsgClientWelcome),
[(uint)Artifact.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = typeof(Artifact.CMsgConnectionStatus),
[(uint)Artifact.EGCBaseClientMsg.k_EMsgGCServerConnectionStatus] = typeof(Artifact.CMsgConnectionStatus),

[(uint)Artifact.ESOMsg.k_ESOMsg_Create] = typeof(Artifact.CMsgSOSingleObject),
[(uint)Artifact.ESOMsg.k_ESOMsg_Destroy] = typeof(Artifact.CMsgSOSingleObject),
[(uint)Artifact.ESOMsg.k_ESOMsg_Update] = typeof(Artifact.CMsgSOSingleObject),
[(uint)Artifact.ESOMsg.k_ESOMsg_UpdateMultiple] = typeof(Artifact.CMsgSOMultipleObjects),
},
[ WellKnownAppIDs.Underlords ] = new Dictionary<uint, Type>
{
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCClientHello] = typeof(Underlords.CMsgClientHello),
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCClientWelcome] = typeof(Underlords.CMsgClientWelcome),
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCServerHello] = typeof(Underlords.CMsgClientHello),
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCServerWelcome] = typeof(Underlords.CMsgClientWelcome),
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = typeof(Underlords.CMsgConnectionStatus),
[(uint)Underlords.EGCBaseClientMsg.k_EMsgGCServerConnectionStatus] = typeof(Underlords.CMsgConnectionStatus),

[(uint)Underlords.ESOMsg.k_ESOMsg_Create] = typeof(Underlords.CMsgSOSingleObject),
[(uint)Underlords.ESOMsg.k_ESOMsg_Destroy] = typeof(Underlords.CMsgSOSingleObject),
[(uint)Underlords.ESOMsg.k_ESOMsg_Update] = typeof(Underlords.CMsgSOSingleObject),
[(uint)Underlords.ESOMsg.k_ESOMsg_UpdateMultiple] = typeof(Underlords.CMsgSOMultipleObjects),
},
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@
<Compile Include="Specializations\TF2\TF2SOHelper.cs" />
<Compile Include="Specializations\TF2\TF2SOMultipleObjectsGCSpecialization.cs" />
<Compile Include="Specializations\TF2\TF2SOSingleObjectGCSpecialization.cs" />
<Compile Include="Specializations\Underlords\UnderlordsSOCacheSubscribedGCSpecialization.cs" />
<Compile Include="Specializations\Underlords\UnderlordsSOHelper.cs" />
<Compile Include="Specializations\Underlords\UnderlordsSOMultipleObjectsGCSpecialization.cs" />
<Compile Include="Specializations\Underlords\UnderlordsSOSingleObjectGCSpecialization.cs" />
<Compile Include="Specializations\UnifiedMessagingHelpers.cs" />
<Compile Include="SteamUtils.cs" />
<Compile Include="StringExtensions.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
using SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2.Specializations
{
class UnderlordsCacheSubscribedGCSpecialization : IGameCoordinatorSpecialization
{
public IEnumerable<KeyValuePair<string, object>> GetExtraObjects(object body, uint appID)
{
if (appID != WellKnownAppIDs.Underlords)
{
yield break;
}

var cacheSubscribed = body as CMsgSOCacheSubscribed;
if (cacheSubscribed == null)
{
yield break;
}

foreach (var bucket in cacheSubscribed.objects)
{
int typeId = bucket.type_id;
foreach (var singleObject in bucket.object_data)
{
var extraNode = ReadExtraObject(singleObject, typeId);
if (extraNode != null)
{
yield return new KeyValuePair<string, object>(string.Format("SO ({0})", extraNode.GetType().Name), extraNode);
}
}
}
}

object ReadExtraObject(byte[] sharedObject, int typeId)
{
try
{
using (var ms = new MemoryStream(sharedObject))
{
Type t;
if (UnderlordsSOHelper.SOTypes.TryGetValue(typeId, out t))
{
return RuntimeTypeModel.Default.Deserialize(ms, null, t);
}
}
}
catch (ProtoException ex)
{
return "Error parsing SO data: " + ex.Message;
}
catch (EndOfStreamException ex)
{
return "Error parsing SO data: " + ex.Message;
}

return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2.Specializations
{
static class UnderlordsSOHelper
{
public static Dictionary<int, Type> SOTypes = new Dictionary<int, Type>()
{
{1, typeof(CSOEconItem)},
{3, typeof(CSOEconClaimCode)},
{5, typeof(CSOItemRecipe)},
{7, typeof(CSOEconGameAccountClient)},
{38, typeof(CSOEconItemDropRateBonus)},
{39, typeof(CSOEconItemLeagueViewPass)},
{40, typeof(CSOEconItemEventTicket)},
{42, typeof(CSOEconItemTournamentPassport)},

{101, typeof(CSODACLobby)},
{102, typeof(CSODACServerDynamicLobby)},
{103, typeof(CSOGameAccountClient)},
{104, typeof(CSODACParty)},
{105, typeof(CSODACServerStaticLobby)},
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
using SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2.Specializations
{
class UnderlordsSOMultipleObjectsGCSpecialization : IGameCoordinatorSpecialization
{
public IEnumerable<KeyValuePair<string, object>> GetExtraObjects(object body, uint appID)
{
if (appID != WellKnownAppIDs.Underlords)
{
yield break;
}

var updateMultiple = body as CMsgSOMultipleObjects;
if (updateMultiple == null)
{
yield break;
}

foreach(var singleObject in updateMultiple.objects_added)
{
var extraNode = ReadExtraObject(singleObject);
if (extraNode != null)
{
yield return new KeyValuePair<string, object>(string.Format("New SO ({0})", extraNode.GetType().Name), extraNode);
}
}

foreach (var singleObject in updateMultiple.objects_modified)
{
var extraNode = ReadExtraObject(singleObject);
if (extraNode != null)
{
yield return new KeyValuePair<string, object>(string.Format("Modified SO ({0})", extraNode.GetType().Name), extraNode);
}
}

foreach (var singleObject in updateMultiple.objects_removed)
{
var extraNode = ReadExtraObject(singleObject);
if (extraNode != null)
{
yield return new KeyValuePair<string, object>(string.Format("Removed SO ({0})", extraNode.GetType().Name), extraNode);
}
}
}

object ReadExtraObject(CMsgSOMultipleObjects.SingleObject sharedObject)
{
try
{
using (var ms = new MemoryStream(sharedObject.object_data))
{
Type t;
if (UnderlordsSOHelper.SOTypes.TryGetValue(sharedObject.type_id, out t))
{
return RuntimeTypeModel.Default.Deserialize(ms, null, t);
}
}
}
catch (ProtoException ex)
{
return "Error parsing SO data: " + ex.Message;
}
catch (EndOfStreamException ex)
{
return "Error parsing SO data: " + ex.Message;
}

return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
using SteamKit2.GC.Underlords.Internal;

namespace NetHookAnalyzer2.Specializations
{
class UnderlordsSOSingleObjectGCSpecialization : IGameCoordinatorSpecialization
{
public IEnumerable<KeyValuePair<string, object>> GetExtraObjects(object body, uint appID)
{
if (appID != WellKnownAppIDs.Underlords)
{
yield break;
}

var updateSingle = body as CMsgSOSingleObject;
if (updateSingle == null)
{
yield break;
}

var extraNode = ReadExtraObject(updateSingle);
if (extraNode != null)
{
yield return new KeyValuePair<string, object>(string.Format("SO ({0})", extraNode.GetType().Name), extraNode);
}
}

object ReadExtraObject(CMsgSOSingleObject sharedObject)
{
try
{
using (var ms = new MemoryStream(sharedObject.object_data))
{
Type t;
if (UnderlordsSOHelper.SOTypes.TryGetValue(sharedObject.type_id, out t))
{
return RuntimeTypeModel.Default.Deserialize(ms, null, t);
}
}
}
catch (ProtoException ex)
{
return "Error parsing SO data: " + ex.Message;
}
catch (EndOfStreamException ex)
{
return "Error parsing SO data: " + ex.Message;
}

return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ static class WellKnownAppIDs
public const uint Dota2 = 570;
public const uint TeamFortress2 = 440;
public const uint Artifact = 583950;
public const uint Underlords = 1046930;
}
}
2 changes: 1 addition & 1 deletion Resources/Protobufs
Submodule Protobufs updated 129 files
9 changes: 9 additions & 0 deletions Resources/Protogen/protos.csv
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,12 @@ tf2,gcsdk_gcmessages.proto,GC\TF2\SteamMsgGCSDK.cs,SteamKit2.GC.TF2.Internal
tf2,gcsystemmsgs.proto,GC\TF2\SteamMsgGCSystem.cs,SteamKit2.GC.TF2.Internal
tf2,steammessages.proto,GC\TF2\SteamMsgBase.cs,SteamKit2.GC.TF2.Internal
tf2,tf_gcmessages.proto,GC\TF2\MsgGC.cs,SteamKit2.GC.TF2.Internal
underlords,steammessages.proto,GC\Underlords\SteamMsgBase.cs,SteamKit2.GC.Underlords.Internal
underlords,dac_gcmessages_common.proto,GC\Underlords\MsgGCCommon.cs,SteamKit2.GC.Underlords.Internal
underlords,dac_gcmessages_client.proto,GC\Underlords\MsgGCClient.cs,SteamKit2.GC.Underlords.Internal
underlords,dac_gcmessages_server.proto,GC\Underlords\MsgGCServer.cs,SteamKit2.GC.Underlords.Internal
underlords,base_gcmessages.proto,GC\Underlords\SteamMsgGC.cs,SteamKit2.GC.Underlords.Internal
underlords,econ_gcmessages.proto,GC\Underlords\SteamMsgGCEcon.cs,SteamKit2.GC.Underlords.Internal
underlords,econ_shared_enums.proto,GC\Underlords\SteamMsgGCEconSharedEnums.cs,SteamKit2.GC.Underlords.Internal
underlords,gcsdk_gcmessages.proto,GC\Underlords\SteamMsgGCSDK.cs,SteamKit2.GC.Underlords.Internal
underlords,gcsystemmsgs.proto,GC\Underlords\SteamMsgGCSystem.cs,SteamKit2.GC.Underlords.Internal
Loading

0 comments on commit 361b0d5

Please sign in to comment.