Welcome to mirror list, hosted at ThFree Co, Russian Federation.

steamclient_manual_153a.cpp « lsteamclient - github.com/ValveSoftware/Proton.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 79d0b775c93e8ad82f524ede5a10a279f1b37e53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
extern "C" {
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
}

#include "steam_defs.h"
#pragma push_macro("__cdecl")
#undef __cdecl
#include "steamworks_sdk_153a/steam_api.h"
#include "steamworks_sdk_153a/isteamnetworkingsockets.h"
#include "steamworks_sdk_153a/isteamnetworkingutils.h"
#include "steamworks_sdk_153a/steamnetworkingtypes.h"
#include "steamworks_sdk_153a/steamnetworkingfakeip.h"
#pragma pop_macro("__cdecl")
#include "steamclient_private.h"

extern "C" {
#define SDKVER_153a
#include "struct_converters.h"
#include "cb_converters.h"
#include "win_constructors.h"

#include "queue.h"

/***** manual struct converter for SteamNetworkingMessage_t *****/

struct msg_wrapper {
    struct winSteamNetworkingMessage_t_153a win_msg;
    struct SteamNetworkingMessage_t *lin_msg;

    void (*orig_FreeData)(SteamNetworkingMessage_t *);

    SLIST_ENTRY(msg_wrapper) entry;
};

static SLIST_HEAD(free_msgs_head, msg_wrapper) free_msgs = SLIST_HEAD_INITIALIZER(free_msgs);
static CRITICAL_SECTION free_msgs_lock = { NULL, -1, 0, 0, 0, 0 };

static void __attribute__((ms_abi)) win_FreeData(struct winSteamNetworkingMessage_t_153a *win_msg)
{
    struct msg_wrapper *msg = CONTAINING_RECORD(win_msg, struct msg_wrapper, win_msg);
    TRACE("%p\n", msg);
    if(msg->orig_FreeData)
    {
        msg->lin_msg->m_pData = msg->win_msg.m_pData;
        msg->orig_FreeData(msg->lin_msg);
    }
}

static void __attribute__((ms_abi)) win_Release(struct winSteamNetworkingMessage_t_153a *win_msg)
{
    struct msg_wrapper *msg = CONTAINING_RECORD(win_msg, struct msg_wrapper, win_msg);
    TRACE("%p\n", msg);
    msg->lin_msg->m_pfnRelease(msg->lin_msg);
    msg->lin_msg = NULL;
    msg->orig_FreeData = NULL;
    EnterCriticalSection(&free_msgs_lock);
    SLIST_INSERT_HEAD(&free_msgs, msg, entry);
    LeaveCriticalSection(&free_msgs_lock);
}

static void lin_FreeData(struct SteamNetworkingMessage_t *lin_msg)
{
    struct msg_wrapper *msg = (struct msg_wrapper *)lin_msg->m_pData; /* ! see assignment, below */
    TRACE("%p\n", msg);
    if(msg->win_msg.m_pfnFreeData)
        ((void (__attribute__((ms_abi))*)(struct winSteamNetworkingMessage_t_153a *))msg->win_msg.m_pfnFreeData)(&msg->win_msg);
}

static struct msg_wrapper *clone_msg(struct SteamNetworkingMessage_t *lin_msg)
{
    struct msg_wrapper *msg;

    EnterCriticalSection(&free_msgs_lock);

    msg = SLIST_FIRST(&free_msgs);

    if(!msg){
        int n;
        /* allocs can be pricey, so alloc in blocks */
#define MSGS_PER_BLOCK 16
        struct msg_wrapper *msgs = (struct msg_wrapper *)HeapAlloc(GetProcessHeap(), 0, sizeof(struct msg_wrapper) * MSGS_PER_BLOCK);
        for(n = 1; n < MSGS_PER_BLOCK; ++n)
            SLIST_INSERT_HEAD(&free_msgs, &msgs[n], entry);
        msg = &msgs[0];
    }else
        SLIST_REMOVE_HEAD(&free_msgs, entry);

    LeaveCriticalSection(&free_msgs_lock);

    msg->lin_msg = lin_msg;

    msg->win_msg.m_pData = msg->lin_msg->m_pData;
    msg->win_msg.m_cbSize = msg->lin_msg->m_cbSize;
    msg->win_msg.m_conn = msg->lin_msg->m_conn;
    msg->win_msg.m_identityPeer = msg->lin_msg->m_identityPeer;
    msg->win_msg.m_nConnUserData = msg->lin_msg->m_nConnUserData;
    msg->win_msg.m_usecTimeReceived= msg->lin_msg->m_usecTimeReceived;
    msg->win_msg.m_nMessageNumber = msg->lin_msg->m_nMessageNumber;
    msg->win_msg.m_pfnFreeData = (void*)win_FreeData;
    msg->win_msg.m_pfnRelease = (void*)win_Release;
    msg->win_msg.m_nChannel = msg->lin_msg->m_nChannel;
    msg->win_msg.m_nFlags = msg->lin_msg->m_nFlags;
    msg->win_msg.m_nUserData = msg->lin_msg->m_nUserData;
    msg->win_msg.m_idxLane = msg->lin_msg->m_idxLane;
    msg->win_msg._pad1__ = msg->lin_msg->_pad1__;

    msg->orig_FreeData = msg->lin_msg->m_pfnFreeData;
    msg->lin_msg->m_pfnFreeData = lin_FreeData;
    /* ! store the wrapper here and restore the original pointer from win_msg before calling orig_FreeData */
    msg->lin_msg->m_pData = msg;

    return msg;
}

void lin_to_win_struct_SteamNetworkingMessage_t_153a(int n_messages, struct SteamNetworkingMessage_t **l, struct winSteamNetworkingMessage_t_153a **w, int max_messages)
{
    int i;

    if(n_messages > 0)
        TRACE("%u %p %p\n", n_messages, l, w);

    for(i = 0; i < n_messages; ++i)
    {
        struct msg_wrapper *msg;

        msg = clone_msg(l[i]);

        w[i] = &msg->win_msg;

        TRACE("done with %u, returned wrapper %p\n", i, msg);
    }

    for(; i < max_messages; ++i)
        w[i] = NULL;
}

int cppISteamNetworkingSockets_SteamNetworkingSockets012_ReceiveMessagesOnConnection(
        void *linux_side, HSteamNetConnection hConn,
        winSteamNetworkingMessage_t_153a **ppOutMessages, int nMaxMessages)
{
    SteamNetworkingMessage_t *lin_ppOutMessages[nMaxMessages];
    int retval = ((ISteamNetworkingSockets*)linux_side)->ReceiveMessagesOnConnection(hConn, lin_ppOutMessages, nMaxMessages);
    lin_to_win_struct_SteamNetworkingMessage_t_153a(retval, lin_ppOutMessages, ppOutMessages, nMaxMessages);
    return retval;
}

int cppISteamNetworkingSockets_SteamNetworkingSockets012_ReceiveMessagesOnPollGroup(
        void *linux_side, HSteamNetPollGroup hPollGroup,
        winSteamNetworkingMessage_t_153a **ppOutMessages, int nMaxMessages)
{
    SteamNetworkingMessage_t *lin_ppOutMessages[nMaxMessages];
    int retval = ((ISteamNetworkingSockets*)linux_side)->ReceiveMessagesOnPollGroup(hPollGroup, lin_ppOutMessages, nMaxMessages);
    lin_to_win_struct_SteamNetworkingMessage_t_153a(retval, lin_ppOutMessages, ppOutMessages, nMaxMessages);
    return retval;
}

void cppISteamNetworkingSockets_SteamNetworkingSockets012_SendMessages(
        void *linux_side, int nMessages, winSteamNetworkingMessage_t_153a **pMessages,
        int64 *pOutMessageNumberOrResult)
{
#define MAX_SEND_MESSAGES 64
    /* use the stack to avoid heap allocation */
    struct SteamNetworkingMessage_t *lin_msgs[MAX_SEND_MESSAGES];
    int i;

    if (nMessages > MAX_SEND_MESSAGES)
    {
        /* if we ever hit this, increase MAX_SEND_MESSAGES appropriately */
        FIXME("Trying to send %u messages, which is more than %u! Will break up into pieces.\n", nMessages, MAX_SEND_MESSAGES);
    }

    while(nMessages)
    {
        for(i = 0; i < nMessages && i < MAX_SEND_MESSAGES; ++i)
        {
            struct msg_wrapper *msg = CONTAINING_RECORD(pMessages[i], struct msg_wrapper, win_msg);
            lin_msgs[i] = msg->lin_msg;

            lin_msgs[i]->m_pData = msg->win_msg.m_pData;
            lin_msgs[i]->m_cbSize = msg->win_msg.m_cbSize;
            lin_msgs[i]->m_conn = msg->win_msg.m_conn;
            lin_msgs[i]->m_identityPeer = msg->win_msg.m_identityPeer;
            lin_msgs[i]->m_nConnUserData = msg->win_msg.m_nConnUserData;
            lin_msgs[i]->m_usecTimeReceived= msg->win_msg.m_usecTimeReceived;
            lin_msgs[i]->m_nMessageNumber = msg->win_msg.m_nMessageNumber;
            lin_msgs[i]->m_nChannel = msg->win_msg.m_nChannel;
            lin_msgs[i]->m_nFlags = msg->win_msg.m_nFlags;
            lin_msgs[i]->m_nUserData = msg->win_msg.m_nUserData;
            lin_msgs[i]->m_idxLane = msg->win_msg.m_idxLane;
            lin_msgs[i]->_pad1__ = msg->win_msg._pad1__;
        }

        ((ISteamNetworkingSockets*)linux_side)->SendMessages(i, lin_msgs, pOutMessageNumberOrResult);

        nMessages -= i;
        pMessages += i;
        if(pOutMessageNumberOrResult)
            pOutMessageNumberOrResult += i;
    }
}

/* from winISteamNetworkingFakeUDPPort.c */
typedef struct __winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001 {
    void *vtable;
    void *linux_side;
} winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001;

void *cppISteamNetworkingSockets_SteamNetworkingSockets012_CreateFakeUDPPort(void *linux_side, int idxFakeServerPort)
{
    ISteamNetworkingFakeUDPPort *lin_iface = ((ISteamNetworkingSockets*)linux_side)->CreateFakeUDPPort(idxFakeServerPort);
    if(!lin_iface)
        return NULL;
    return create_winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001(lin_iface);
}

int cppISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001_ReceiveMessages(void *linux_side, winSteamNetworkingMessage_t_153a ** ppOutMessages, int nMaxMessages)
{
    SteamNetworkingMessage_t *lin_ppOutMessages[nMaxMessages];
    int retval = ((ISteamNetworkingFakeUDPPort*)linux_side)->ReceiveMessages(lin_ppOutMessages, nMaxMessages);
    lin_to_win_struct_SteamNetworkingMessage_t_153a(retval, lin_ppOutMessages, ppOutMessages, nMaxMessages);
    return retval;
}

void cppISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001_DestroyFakeUDPPort(void *linux_side)
{
    winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001 *win_side =
        (winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001 *)
        (char *)linux_side - offsetof(winISteamNetworkingFakeUDPPort_SteamNetworkingFakeUDPPort001, linux_side);
    ((ISteamNetworkingFakeUDPPort*)linux_side)->DestroyFakeUDPPort();
    HeapFree(GetProcessHeap(), 0, win_side);
}

#pragma pack( push, 8 )
struct winSteamNetConnectionStatusChangedCallback_t_712 {
    HSteamNetConnection m_hConn;
    SteamNetConnectionInfo_t m_info __attribute__((aligned(8)));
    ESteamNetworkingConnectionState m_eOldState;
}  __attribute__ ((ms_struct));
#pragma pack( pop )

typedef void (*CDECL win_FnSteamNetConnectionStatusChanged)(winSteamNetConnectionStatusChangedCallback_t_712 *);
static win_FnSteamNetConnectionStatusChanged win_SteamNetConnectionStatusChanged;

static void lin_SteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t *l_dat)
{
    win_FnSteamNetConnectionStatusChanged fn = win_SteamNetConnectionStatusChanged;
    if(fn){
        struct winSteamNetConnectionStatusChangedCallback_t_712 w_dat;
        cb_SteamNetConnectionStatusChangedCallback_t_712(l_dat, &w_dat);
        fn(&w_dat);
    }
}

typedef void (*CDECL win_FnSteamNetAuthenticationStatusChanged)(SteamNetAuthenticationStatus_t *);
extern win_FnSteamNetAuthenticationStatusChanged win_SteamNetAuthenticationStatusChanged;

typedef void (*CDECL win_FnSteamRelayNetworkStatusChanged)(SteamRelayNetworkStatus_t *);
extern win_FnSteamRelayNetworkStatusChanged win_SteamRelayNetworkStatusChanged;

typedef void (*CDECL win_FnSteamNetworkingMessagesSessionRequest)(SteamNetworkingMessagesSessionRequest_t *);
extern win_FnSteamNetworkingMessagesSessionRequest win_SteamNetworkingMessagesSessionRequest;

typedef void (*CDECL win_FnSteamNetworkingMessagesSessionFailed)(SteamNetworkingMessagesSessionFailed_t *);
extern win_FnSteamNetworkingMessagesSessionFailed win_SteamNetworkingMessagesSessionFailed;

extern void lin_SteamNetworkingMessagesSessionRequest(SteamNetworkingMessagesSessionRequest_t *dat);
extern void lin_SteamNetworkingMessagesSessionFailed(SteamNetworkingMessagesSessionFailed_t *dat);
extern void lin_SteamRelayNetworkStatusChanged(SteamRelayNetworkStatus_t *dat);
extern void lin_SteamNetAuthenticationStatusChanged(SteamNetAuthenticationStatus_t *dat);

bool cppISteamNetworkingUtils_SteamNetworkingUtils004_SetConfigValue(void *linux_side,
        ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType,
        intptr_t scopeObj, ESteamNetworkingConfigDataType eDataType, const void *pArg)
{
    bool ret;
    void *lin_fn; /* api requires passing pointer-to-pointer */

    switch(eValue){

#define CASE(x, y) \
    case k_ESteamNetworkingConfig_Callback_##x: \
        if(!pArg){ \
            ret = ((ISteamNetworkingUtils*)linux_side)->SetConfigValue(eValue, eScopeType, scopeObj, eDataType, NULL); \
        }else{ \
            if(*(void **)pArg == NULL) \
                lin_fn = NULL; \
            else \
                lin_fn = (void *)&lin_##y; \
            ret = ((ISteamNetworkingUtils*)linux_side)->SetConfigValue(eValue, eScopeType, scopeObj, eDataType, &lin_fn); \
            if(ret) \
                win_##y = *(win_Fn##y*)pArg; \
        } \
        return ret;

    CASE(ConnectionStatusChanged,       SteamNetConnectionStatusChanged)
    CASE(AuthStatusChanged,             SteamNetAuthenticationStatusChanged)
    CASE(RelayNetworkStatusChanged,     SteamRelayNetworkStatusChanged)
    CASE(MessagesSessionRequest,        SteamNetworkingMessagesSessionRequest)
    CASE(MessagesSessionFailed,         SteamNetworkingMessagesSessionFailed)

#undef CASE

    default:
        return ((ISteamNetworkingUtils*)linux_side)->SetConfigValue((ESteamNetworkingConfigValue)eValue, (ESteamNetworkingConfigScope)eScopeType, (intptr_t)scopeObj, (ESteamNetworkingConfigDataType)eDataType, (const void *)pArg);
    }
}

SteamNetworkingMessage_t *cppISteamNetworkingUtils_SteamNetworkingUtils004_AllocateMessage(
        void *linux_side, int cbAllocateBuffer)
{
    struct msg_wrapper *msg;
    SteamNetworkingMessage_t *retval = ((ISteamNetworkingUtils*)linux_side)->AllocateMessage(cbAllocateBuffer);

    msg = clone_msg(retval);

    return (SteamNetworkingMessage_t*)&msg->win_msg;
}

const char * cppISteamInput_SteamInput006_GetGlyphPNGForActionOrigin(void *linux_side, EInputActionOrigin eOrigin, ESteamInputGlyphSize eSize, uint32 unFlags)
{
    const char *path_result;
    path_result = ((ISteamInput*)linux_side)->GetGlyphPNGForActionOrigin((EInputActionOrigin)eOrigin, eSize, unFlags);
    return steamclient_isteaminput_getglyph_png(eOrigin, eSize, unFlags, path_result);
}

const char * cppISteamInput_SteamInput006_GetGlyphSVGForActionOrigin(void *linux_side, EInputActionOrigin eOrigin, uint32 unFlags)
{
    const char *path_result;
    path_result = ((ISteamInput*)linux_side)->GetGlyphSVGForActionOrigin((EInputActionOrigin)eOrigin, unFlags);
    return steamclient_isteaminput_getglyph_svg(eOrigin, unFlags, path_result);
}

const char * cppISteamInput_SteamInput006_GetGlyphForActionOrigin_Legacy(void *linux_side, EInputActionOrigin eOrigin)
{
    const char *path_result;
    path_result = ((ISteamInput*)linux_side)->GetGlyphForActionOrigin_Legacy((EInputActionOrigin)eOrigin);
    return steamclient_isteaminput_getglyph(eOrigin, path_result);
}

const char * cppISteamInput_SteamInput006_GetGlyphForXboxOrigin(void *linux_side, EXboxOrigin eOrigin)
{
    const char *path_result;
    path_result = ((ISteamInput*)linux_side)->GetGlyphForXboxOrigin((EXboxOrigin)eOrigin);
    return steamclient_isteaminput_getglyph_xbox(eOrigin, path_result);
}

}