1#include <engine/steam.h>
2
3#include <base/system.h>
4#include <engine/shared/config.h>
5
6#include <steam/steam_api_flat.h>
7
8class CSteam : public ISteam
9{
10 HSteamPipe m_SteamPipe;
11 ISteamApps *m_pSteamApps;
12 ISteamFriends *m_pSteamFriends;
13 char m_aPlayerName[16];
14 bool m_GotConnectAddr;
15 NETADDR m_ConnectAddr;
16
17public:
18 CSteam()
19 {
20 SteamAPI_ManualDispatch_Init();
21 m_SteamPipe = SteamAPI_GetHSteamPipe();
22 m_pSteamApps = SteamAPI_SteamApps_v008();
23 m_pSteamFriends = SteamAPI_SteamFriends_v017();
24
25 ReadLaunchCommandLine();
26 str_copy(dst&: m_aPlayerName, src: SteamAPI_ISteamFriends_GetPersonaName(pSelf: m_pSteamFriends));
27 }
28 ~CSteam() override
29 {
30 SteamAPI_Shutdown();
31 }
32
33 void ParseConnectString(const char *pConnect)
34 {
35 if(pConnect[0])
36 {
37 NETADDR Connect;
38 if(net_host_lookup(hostname: pConnect, addr: &Connect, types: NETTYPE_ALL) == 0)
39 {
40 m_ConnectAddr = Connect;
41 m_GotConnectAddr = true;
42 }
43 else
44 {
45 dbg_msg(sys: "steam", fmt: "got unparsable connect string: '%s'", pConnect);
46 }
47 }
48 }
49
50 void ReadLaunchCommandLine()
51 {
52 char aConnect[NETADDR_MAXSTRSIZE];
53 int ConnectSize = SteamAPI_ISteamApps_GetLaunchCommandLine(pSelf: m_pSteamApps, pBuffer: aConnect, BufferSize: sizeof(aConnect));
54 if(ConnectSize >= NETADDR_MAXSTRSIZE)
55 {
56 ConnectSize = NETADDR_MAXSTRSIZE - 1;
57 }
58 aConnect[ConnectSize] = 0;
59 m_GotConnectAddr = false;
60 ParseConnectString(pConnect: aConnect);
61 }
62
63 void OnGameRichPresenceJoinRequested(GameRichPresenceJoinRequested_t *pEvent)
64 {
65 ParseConnectString(pConnect: pEvent->m_aRGCHConnect);
66 }
67
68 const char *GetPlayerName() override
69 {
70 return m_aPlayerName;
71 }
72
73 const NETADDR *GetConnectAddress() override
74 {
75 if(m_GotConnectAddr)
76 {
77 return &m_ConnectAddr;
78 }
79 else
80 {
81 return 0;
82 }
83 }
84 void ClearConnectAddress() override
85 {
86 m_GotConnectAddr = false;
87 }
88
89 void Update() override
90 {
91 SteamAPI_ManualDispatch_RunFrame(SteamPipe: m_SteamPipe);
92 CallbackMsg_t Callback;
93 while(SteamAPI_ManualDispatch_GetNextCallback(SteamPipe: m_SteamPipe, pCallbackMsg: &Callback))
94 {
95 switch(Callback.m_iCallback)
96 {
97 case NewUrlLaunchParameters_t::k_iCallback:
98 ReadLaunchCommandLine();
99 break;
100 case GameRichPresenceJoinRequested_t::k_iCallback:
101 OnGameRichPresenceJoinRequested(pEvent: (GameRichPresenceJoinRequested_t *)Callback.m_pubParam);
102 break;
103 default:
104 if(g_Config.m_Debug)
105 {
106 dbg_msg(sys: "steam/dbg", fmt: "unhandled callback id=%d", Callback.m_iCallback);
107 }
108 }
109 SteamAPI_ManualDispatch_FreeLastCallback(SteamPipe: m_SteamPipe);
110 }
111 }
112 void ClearGameInfo() override
113 {
114 SteamAPI_ISteamFriends_ClearRichPresence(pSelf: m_pSteamFriends);
115 }
116 void SetGameInfo(const NETADDR &ServerAddr, const char *pMapName, bool AnnounceAddr) override
117 {
118 if(AnnounceAddr)
119 {
120 char aServerAddr[NETADDR_MAXSTRSIZE];
121 net_addr_str(addr: &ServerAddr, string: aServerAddr, max_length: sizeof(aServerAddr), add_port: true);
122 SteamAPI_ISteamFriends_SetRichPresence(pSelf: m_pSteamFriends, pKey: "connect", pValue: aServerAddr);
123 SteamAPI_ISteamFriends_SetRichPresence(pSelf: m_pSteamFriends, pKey: "steam_player_group", pValue: aServerAddr);
124 }
125
126 SteamAPI_ISteamFriends_SetRichPresence(pSelf: m_pSteamFriends, pKey: "map", pValue: pMapName);
127 SteamAPI_ISteamFriends_SetRichPresence(pSelf: m_pSteamFriends, pKey: "status", pValue: pMapName);
128 SteamAPI_ISteamFriends_SetRichPresence(pSelf: m_pSteamFriends, pKey: "steam_display", pValue: "#Status");
129 }
130};
131
132class CSteamStub : public ISteam
133{
134 const char *GetPlayerName() override { return 0; }
135 const NETADDR *GetConnectAddress() override { return 0; }
136 void ClearConnectAddress() override {}
137 void Update() override {}
138 void ClearGameInfo() override {}
139 void SetGameInfo(const NETADDR &ServerAddr, const char *pMapName, bool AnnounceAddr) override {}
140};
141
142ISteam *CreateSteam()
143{
144 if(!SteamAPI_Init())
145 {
146 return new CSteamStub();
147 }
148 return new CSteam();
149}
150