TeamForbiddenLLC / warfork-qfusion

Warfork is powered by Qfusion a 3D game engine. Qfusion is a fork of id Tech 2, popularly known as the Quake II engine. Qfusion is free and open-source software subject to the terms of the GNU General Public License.
https://warfork.com
109 stars 43 forks source link

feature: steam shim rpc interface #362

Open pollend opened 5 months ago

pollend commented 5 months ago

This is the standardized interface for steam shim.

DECLARE_TYPEDEF_METHOD( int, STEAMSHIM_dispatch );
DECLARE_TYPEDEF_METHOD( int, STEAMSHIM_sendRPC, void *req, uint32_t size, void *self, STEAMSHIM_rpc_handle rpc, uint32_t *syncIndex );
DECLARE_TYPEDEF_METHOD( int, STEAMSHIM_waitDispatchSync, uint32_t syncIndex ); // wait on the dispatch loop does not trigger steam callbacks
DECLARE_TYPEDEF_METHOD( void, STEAMSHIM_subscribeEvent, uint32_t id, void *self, STEAMSHIM_evt_handle evt );
DECLARE_TYPEDEF_METHOD( void, STEAMSHIM_unsubscribeEvent, uint32_t id, STEAMSHIM_evt_handle evt );
DECLARE_TYPEDEF_METHOD( bool, STEAMSHIM_active );

examples:

static void CG_CallbackRequestAvatar(uint64_t steamid, uint8_t *avatar){
    for (int i = 0; i < gs.maxclients; i++){
        cg_clientInfo_t *ci = &cgs.clientInfo[i];
        if (ci->steamid == steamid){
            ci->avatar = trap_R_RegisterRawPic(va("avatar-%llu", ci->steamid), 32, 32, avatar, 4);
            return;
        }
    }
}
static void CG_RPC_cb_requestAvatar( void *self, struct steam_rpc_pkt_s *rec )
{
    assert(rec->common.cmd == RPC_REQUEST_AVATAR);
    if(rec->avatar_recv.width == 0 || rec->avatar_recv.height == 0) {
        return;
    }

    cg_clientInfo_t *target = (cg_clientInfo_t *)self;
    for( int i = 0; i < gs.maxclients; i++ ) {
        cg_clientInfo_t *ci = &cgs.clientInfo[i];
        if( ci == target ) {
            ci->avatar = trap_R_RegisterRawPic( va( "avatar-%llu", ci->steamid ), rec->avatar_recv.width, rec->avatar_recv.height, rec->avatar_recv.buf, 4 );
            return;
        }
    }
}

...

void CG_initPlayer() {
    STEAMSHIM_subscribeEvent(EVT_PERSONA_CHANGED, NULL, CG_EVT_cb_personaChanged);
}

void CG_deinitPlayer() {
    STEAMSHIM_unsubscribeEvent(EVT_PERSONA_CHANGED, CG_EVT_cb_personaChanged);
}
...
if (s && atol(s)){
          ci->steamid = atoll(s);
          struct steam_avatar_req_s req;
          req.cmd = RPC_REQUEST_AVATAR;
          req.size = STEAM_AVATAR_SMALL;
          req.steamID = ci->steamid;
          STEAMSHIM_sendRPC(&req, sizeof(struct steam_avatar_req_s), ci, CG_RPC_cb_requestAvatar, NULL);
}
velzie commented 1 month ago

i'm actually going to merge this so that my pr will look less messy in review