static void xmpp_iq_gameroom_sync_cb(const char *msg_id, const char *msg, void *args) { char *data = wf_get_query_content(msg); int room_status = get_info_int(data, "status='", "'", NULL); if (room_status == 2) { t_uid id; idh_generate_unique_id(&id); idh_register(&id, 0, xmpp_iq_session_join_cb, NULL); send_stream_format(session.wfs, "<iq id='%s' to='masterserver@warface/%s' type='get'>" " <query xmlns='urn:cryonline:k01'>" " <session_join/>" " </query>" "</iq>", &id, session.channel); char *sessionid = get_info(data, "session id='", "'", NULL); if (sessionid != NULL && sessionid[0]) printf("Session id: %s\n", sessionid); free(sessionid); } free(data); }
static void xmpp_iq_gameroom_update_pvp_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <data query_name='gameroom_update_pvp' compressedData='...' originalSize='42'/> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type ^ XMPP_TYPE_ERROR) { char *data = wf_get_query_content(msg); if (data == NULL) return; gameroom_sync(data); if (a->cb) a->cb(a->args); free(data); } free(a); }
static void xmpp_iq_clan_masterbanner_update_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='k01.warface' type='get'> <query xmlns='urn:cryonline:k01'> <clan_masterbanner_update master_badge='4294967295' master_stripe='20016' master_mark='7500'/> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; session.profile.clan.master.badge = get_info_int(data, "master_badge='", "'", NULL); session.profile.clan.master.stripe = get_info_int(data, "master_stripe='", "'", NULL); session.profile.clan.master.mark = get_info_int(data, "master_mark='", "'", NULL); free(data); }
static void xmpp_iq_get_achievements_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer: <iq from='masterserver@warface/xx' type='result'> <query xmlns='urn:cryonline:k01'> <get_achievements> <achievement profile_id="1597755"> <chunk achievement_id="51" progress="100000" completion_time="1461010526"/> <chunk achievement_id="52" progress="522318" completion_time="0"/> <chunk achievement_id="53" progress="522318" completion_time="0"/> <chunk achievement_id="54" progress="10" completion_time="1459026091"/> </achievement> ... </get_achievements> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type ^ XMPP_TYPE_ERROR) { char *data = wf_get_query_content(msg); if (data != NULL) { /* Fetch chunks */ { unsigned int achievement_count = 0; const char *m = data; while ((m = strstr(m, "<chunk "))) { char *chunk = get_info(m, "<chunk ", "/>", NULL); unsigned int completion_time = get_info_int(chunk, "completion_time='", "'", NULL); if (completion_time > 0) ++achievement_count; free(chunk); ++m; } if (achievement_count > 0) session.profile.stats.challenges_completed = achievement_count; } } free(data); } if (a->cb) a->cb(msg, type, a->args); free(a); }
static void xmpp_iq_gameroom_quickplay_succeeded_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='k01.warface' type='get'> <query xmlns='urn:cryonline:k01'> <gameroom_quickplay_succeeded uid='xxxxxxxxxxxxxx' /> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; char *uid = get_info(data, "uid='", "'", NULL); if (uid != NULL) { quickplay_succeeded(uid); xmpp_send_iq_result( JID_K01, msg_id, "<query xmlns='urn:cryonline:k01'>" "<gameroom_quickplay_succeeded uid='%s'/>" "</query>", uid); } free(uid); free(data); }
static void xmpp_iq_gameroom_open_cb ( const char *msg, enum xmpp_msg_type type, void *args ) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <data query_name='gameroom_open' compressedData='...' originalSize='42'/> </query> </iq> */ struct cb_args *a = ( struct cb_args * ) args; if ( type & XMPP_TYPE_ERROR ) { free ( a ); return; } session.gameroom.joined = 1; /* Leave previous room if any */ if ( session.gameroom.jid != NULL ) { xmpp_presence ( session.gameroom.jid, 1, NULL, NULL ); free ( session.gameroom.group_id ); session.gameroom.group_id = NULL; free ( session.gameroom.jid ); session.gameroom.jid = NULL; } xmpp_iq_player_status ( STATUS_ONLINE | STATUS_ROOM ); char *data = wf_get_query_content ( msg ); char *room = get_info ( data, "room_id='", "'", "Room ID" ); free ( data ); if ( room ) { /* Join XMPP room */ char *room_jid; FORMAT ( room_jid, "*****@*****.**", session.online.channel, room ); xmpp_presence ( room_jid, 0, NULL, NULL ); session.gameroom.jid = room_jid; } if ( a->fun != NULL ) a->fun ( room, a->args ); free ( room ); free ( a ); }
void xmpp_iq_broadcast_session_result_cb ( const char *msg_id, const char *msg, void *args ) { /* <iq from='k01.warface' to='22910345@warface/GameClient' type='get' id='1343823563'><query xmlns='urn:cryonline:k01'><data query_name='broadcast_session_result' compressedData='...' originalSize='4185'/></query></iq> */ /* <broadcast_session_result bcast_receivers='20511692@warface/GameClient,22910345@warface/GameClient,22061196@warface/GameClient,22911131@warface/GameClient,22911515@warface/GameClient'><player_result nickname='Tastan' experience='3900' pvp_rating_points='0' money='1800' gained_crown_money='0' no_crown_rewards='1' sponsor_points='0' bonus_experience='0' bonus_money='0' bonus_sponsor_points='0' experience_boost='0' money_boost='0' sponsor_points_boost='0' experience_boost_percent='0' money_boost_percent='0' sponsor_points_boost_percent='0' completed_stages='13' is_vip='0' score='44277' dynamic_multipliers_info='' dynamic_crown_multiplier='1'><profile_progression_update profile_id='1597755' mission_unlocked='none,trainingmission,easymission,normalmission,hardmission,survivalmission,zombieeasy,zombienormal,zombiehard,campaignsections,campaignsection1,campaignsection2,campaignsection3,volcanoeasy,volcanonormal,volcanohard,all' tutorial_unlocked='7' class_unlocked='29'/></player_result><player_result nickname='DevilsBitch6' experience='3900' pvp_rating_points='0' money='1800' gained_crown_money='0' no_crown_rewards='1' sponsor_points='0' bonus_experience='0' bonus_money='0' bonus_sponsor_points='0' experience_boost='0' money_boost='0' sponsor_points_boost='0' experience_boost_percent='0' money_boost_percent='0' sponsor_points_boost_percent='0' completed_stages='13' is_vip='0' score='44277' dynamic_multipliers_info='' dynamic_crown_multiplier='1'><profile_progression_update profile_id='2383428' mission_unlocked='none,trainingmission,easymission,normalmission,hardmission,survivalmission,zombieeasy,zombienormal,campaignsections,campaignsection1,campaignsection2,campaignsection3,volcanoeasy,volcanonormal,volcanohard,all' tutorial_unlocked='7' class_unlocked='5'/></player_result><player_result nickname='Nebel.' experience='3900' pvp_rating_points='0' money='2070' gained_crown_money='0' no_crown_rewards='1' sponsor_points='0' bonus_experience='0' bonus_money='0' bonus_sponsor_points='0' experience_boost='0' money_boost='270' sponsor_points_boost='0' experience_boost_percent='0' money_boost_percent='0.15' sponsor_points_boost_percent='0' completed_stages='13' is_vip='0' score='44277' dynamic_multipliers_info='' dynamic_crown_multiplier='1'><profile_progression_update profile_id='2108267' mission_unlocked='none,trainingmission,easymission,normalmission,hardmission,survivalmission,zombieeasy,zombienormal,zombiehard,campaignsections,campaignsection1,campaignsection2,campaignsection3,volcanoeasy,volcanonormal,volcanohard,all' tutorial_unlocked='7' tutorial_passed='7' class_unlocked='29'/></player_result><player_result nickname='DevilsBitch7' experience='3900' pvp_rating_points='0' money='1800' gained_crown_money='0' no_crown_rewards='1' sponsor_points='0' bonus_experience='0' bonus_money='0' bonus_sponsor_points='0' experience_boost='0' money_boost='0' sponsor_points_boost='0' experience_boost_percent='0' money_boost_percent='0' sponsor_points_boost_percent='0' completed_stages='13' is_vip='0' score='44277' dynamic_multipliers_info='' dynamic_crown_multiplier='1'><profile_progression_update profile_id='2383432' mission_unlocked='none,trainingmission,easymission,normalmission,hardmission,survivalmission,zombieeasy,zombienormal,campaignsections,campaignsection1,campaignsection2,campaignsection3,volcanoeasy,volcanonormal,volcanohard,all' tutorial_unlocked='7' class_unlocked='5'/></player_result><player_result nickname='DevilsBitch8' experience='3900' pvp_rating_points='0' money='1800' gained_crown_money='0' no_crown_rewards='1' sponsor_points='3000' bonus_experience='0' bonus_money='0' bonus_sponsor_points='0' experience_boost='0' money_boost='0' sponsor_points_boost='0' experience_boost_percent='0' money_boost_percent='0' sponsor_points_boost_percent='0' completed_stages='13' is_vip='0' score='44277' dynamic_multipliers_info='' dynamic_crown_multiplier='1'><profile_progression_update profile_id='2383439' mission_unlocked='none,trainingmission,easymission,normalmission,hardmission,zombieeasy,zombienormal,volcanoeasy,volcanonormal,volcanohard,all' tutorial_unlocked='7' class_unlocked='5'/></player_result></broadcast_session_result> */ char *data = wf_get_query_content ( msg ); char *begin; FORMAT ( begin, "player_result nickname='%s'", session.profile.nickname ); char *content = get_info ( data, begin, "</player_result>", NULL ); int xp_gained = get_info_int ( content, "experience='", "'", NULL ); int money_earned = get_info_int ( content, "money='", "'", NULL ); int crowns_earned = get_info_int ( content, "gained_crown_money='", "'", NULL ); int no_crowns = get_info_int ( content, "no_crown_rewards='", "'", NULL ); int vp_gained = get_info_int ( content, "sponsor_points='", "'", NULL ); int score = get_info_int ( content, "score='", "'", NULL ); session.profile.experience += xp_gained; session.profile.money.game += money_earned; session.profile.money.crown += crowns_earned; char *rewards; FORMAT ( rewards, "SCORE = %-8d XP = %-6d MONEY = %-6d", score, xp_gained, money_earned ); if ( vp_gained ) { char *old_rewards = strdup ( rewards ); FORMAT ( rewards, "%s VP = %-6d", old_rewards, vp_gained ); free ( old_rewards ); } if ( !no_crowns ) { char *old_rewards = strdup ( rewards ); FORMAT ( rewards, "%s CROWNS = %-6d", old_rewards, crowns_earned ); free ( old_rewards ); } LOGPRINT ( "%-20s " BOLD "%s\n", "GAME REWARDS", rewards ); LOGPRINT ( "%-20s " BOLD "%d\n", "EXPERIENCE", session.profile.experience ); LOGPRINT ( "%-20s " BOLD "%d\n", "MONEY", session.profile.money ); free ( data ); free ( content ); }
static void xmpp_iq_session_join_cb(const char *msg, void *args) { char *data = wf_get_query_content(msg); char *ip = get_info(data, "hostname='", "'", NULL); int port = get_info_int(data, "port='", "'", NULL); printf("Game room started! Leave... (IP/PORT: %s %d)\n", ip, port); free(ip); free(data); xmpp_iq_gameroom_leave(); }
static void xmpp_iq_gameroom_sync_cb(const char *msg_id, const char *msg, void *args) { char *data = wf_get_query_content(msg); int room_status = get_info_int(data, "status='", "'", NULL); if (room_status == 2) { printf("Game room started! Leave...\n"); xmpp_iq_gameroom_leave(); } free(data); }
static void xmpp_iq_preinvite_invite_cb(const char *msg_id, const char *msg, void *args) { /* Accept any preinvite <iq from='xxxx@warface/GameClient' id='uid000000e9' type='get'> <query xmlns='urn:cryonline:k01'> <preinvite_invite from='xxxxxxxx' uid='xxxxxxx' ms_resource='pve_11' channel_type='pve'/> </query> </iq> */ char *jid = get_info(msg, "from='", "'", NULL); char *data = wf_get_query_content(msg); if (!data) return; char *resource = get_info(data, "ms_resource='", "'", "Resource"); char *uid = get_info(data, "uid='", "'", "UUID"); if (jid && resource && uid) { send_stream_format(session.wfs, "<iq to='%s' type='result'>" " <query xmlns='urn:cryonline:k01'>" " <preinvite_invite uid='%s'/>" " </query>" "</iq>", msg_id, uid); send_stream_format(session.wfs, "<iq to='%s' type='get'>" " <query xmlns='urn:cryonline:k01'>" " <preinvite_response uid='%s' accepted='1'" " pid='%s' from='%s'/>" " </query>" "</iq>", jid, uid, session.profile_id, session.nickname); free(uid); free(resource); } free(data); free(jid); }
static void xmpp_iq_peer_status_update_cb(const char *msg_id, const char *msg, void *args) { /* Answer <iq from='xxxxxxx@warface/GameClient' type='get'> <query xmlns='urn:cryonline:k01'> <peer_status_update nickname='xxxx' profile_id='xxxx' status='13' experience='xxxx' place_token='' place_info_token=''/> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; char *jid = get_info(msg, "from='", "'", NULL); char *nick = get_info(data, "nickname='", "'", NULL); char *pid = get_info(data, "profile_id='", "'", NULL); int status = get_info_int(data, "status='", "'", NULL); int exp = get_info_int(data, "experience='", "'", NULL); #ifdef DBUS_API dbus_api_emit_status_update(nick, status, exp, 0); #endif /* DBUS_API */ if (status == STATUS_OFFLINE || status & STATUS_LEFT) friend_list_update(NULL, nick, pid, status, exp); else friend_list_update(jid, nick, pid, status, exp); xmpp_send_iq_result( JID(jid), msg_id, "<query xmlns='urn:cryonline:k01'>" " <peer_status_update/>" "</query>", NULL); free(jid); free(nick); free(pid); free(data); }
static void xmpp_iq_preinvite_response_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='k01.warface' type='get'> <query xmlns='urn:cryonline:k01'> <preinvite_response uid='xxxxxxxxxxxxxxx' accepted='1' pid='xxxxxx' from='xxxxx'/> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; char *jid = get_info(msg, "from='", "'", NULL); char *from = get_info(data, "from='", "'", NULL); char *uid = get_info(data, "uid='", "'", NULL); char *pid = get_info(data, "pid='", "'", NULL); int accepted = get_info_int(data, "accepted='", "'", NULL); if (uid != NULL && jid != NULL && pid != NULL && from != NULL) { quickplay_preinvite_response(uid, jid, accepted); xmpp_send_iq_result( JID(jid), msg_id, "<query xmlns='urn:cryonline:k01'>" " <preinvite_response uid='%s' accepted='%d' from='%s' pid='%s'/>" "</query>", uid, accepted, from, pid); } free(from); free(jid); free(pid); free(uid); free(data); }
static void xmpp_iq_missions_get_list_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer: <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <data query_name='missions_get_list' compressedData='...' originalSize='42'/> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type & XMPP_TYPE_ERROR) { free(a); return; } char *data = wf_get_query_content(msg); if (!data) { free(a); return; } /* Content: <missions_get_list> <mission mission_key='0a88e814-12d9-4b49-ad4a-00416761a87b' no_teams='1' name='@snow_mission_survival_02' setting='survival/snow_fortress_base' mode='pve' mode_name='@PvE_game_mode_desc' mode_icon='pve_icon' description='@snow_survival_mission_desc_02' image='mapImgSurvivalSnow2' difficulty='survival' type='campaignsection2' time_of_day='11:30'> <objectives factor='1'> <objective id='0' type='primary'/> </objectives> </mission> ... <mission mission_key="b9b44f56-c693-4eea-af08-31cddc0402b7" no_teams="1" name="@ct_mission_easy05_2" setting="china/china_base" mode="pve" mode_name="@PvE_game_mode_desc" mode_icon="pve_icon" description="@mission_desc_china_j05" image="mapImgCTj05_normal" difficulty="hard" type="hardmission" time_of_day="9:06"> <objectives factor="2"> <objective id="0" type="primary"/> <objective id="13" type="secondary"/> <objective id="17" type="secondary"/> </objectives> <CrownRewardsThresholds> <TotalPerformance bronze="29595" silver="41855" gold="120220"/> <Time bronze="4193094" silver="4193334" gold="4193374"/> </CrownRewardsThresholds> <CrownRewards bronze="7" silver="19" gold="34"/> </mission> ... </missions_get_list> */ struct list *mission_list = mission_list_new(); int hash = get_info_int(data, " hash='", "'", NULL); int content_hash = get_info_int(data, "content_hash='", "'", NULL); const char *m = strstr(data, "<missions_get_list"); if (m != NULL) { m += sizeof ("<missions_get_list"); while ((m = strstr(m, "<mission"))) { char *ms = get_info(m, "<mission ", "</mission>", NULL); m += sizeof ("<mission"); struct mission *mi = calloc(1, sizeof (struct mission)); mi->mission_key = get_info(ms, "mission_key='", "'", NULL); mi->no_team = get_info_int(ms, "no_team='", "'", NULL); mi->setting = get_info(ms, "setting='", "'", NULL); mi->mode = get_info(ms, "mode='", "'", NULL); mi->mode_name = get_info(ms, "mode_name='", "'", NULL); mi->mode_icon = get_info(ms, "mode_icon='", "'", NULL); mi->description = get_info(ms, "description='", "'", NULL); mi->image = get_info(ms, "image='", "'", NULL); mi->difficulty = get_info(ms, "difficulty='", "'", NULL); mi->type = get_info(ms, "type='", "'", NULL); mi->time_of_day = get_info(ms, "time_of_day='", "'", NULL); char *c_reward = get_info(ms, "<CrownRewards ", ">", NULL); { if (c_reward != NULL) mi->crown_reward_gold = get_info_int(c_reward, "gold='", "'", NULL); free(c_reward); } char *c_perf = get_info(ms, "<TotalPerformance ", ">", NULL); { if (c_perf != NULL) mi->crown_perf_gold = get_info_int(c_perf, "gold='", "'", NULL); free(c_perf); } char *c_time = get_info(ms, "<Time ", ">", NULL); { if (c_time != NULL) { mi->crown_time_gold = get_info_int(c_time, "gold='", "'", NULL); mi->crown_time_gold = (1 << 22) - mi->crown_time_gold; } free(c_time); } { char *name = strdup(mi->type); char *p = strstr(name, "mission"); if (p != NULL) *p = 0; char *new_name = strdup(name); int counter = 1; const struct mission *same_name = NULL; while ((same_name = list_get(mission_list, new_name)) != NULL) { ++counter; free(new_name); FORMAT(new_name, "%s_%i", name, counter); } mi->name = new_name; free(name); } list_add(mission_list, mi); free(ms); } } pvp_maps_add_to_list(mission_list); if (a->fun != NULL) a->fun(mission_list, hash, content_hash, a->args); free(a); free(data); }
static void xmpp_iq_gameroom_update_pvp_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <data query_name='gameroom_update_pvp' compressedData='...' originalSize='42'/> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type & XMPP_TYPE_ERROR) { const char *reason = NULL; int code = get_info_int(msg, "code='", "'", NULL); int custom_code = get_info_int(msg, "custom_code='", "'", NULL); switch (code) { case 8: switch (custom_code) { case 1: reason = LANG(error_unknown_mission); break; case 7: reason = LANG(error_room_started); break; default: break; } break; default: break; } if (reason != NULL) eprintf("%s (%s)", LANG(error_gameroom_setinfo), reason); else eprintf("%s (%i:%i)", LANG(error_gameroom_setinfo), code, custom_code); } else { char *data = wf_get_query_content(msg); if (data == NULL) return; gameroom_sync(data); status_set(session.online.status); if (a->cb) a->cb(a->args); free(data); } free(a); }
static void xmpp_iq_friend_list_cb ( const char *msg_id, const char *msg, void *args ) { /* Record friends to list <iq from='masterserver@warface/pve_12' type='get'> <query xmlns='urn:cryonline:k01'> <friend_list> <friend jid='XXX' profile_id='XXX' nickname='XXX' status='XXX' experience='XXX' location='XXX'/> <friend jid='XXX' profile_id='XXX' nickname='XXX' status='XXX' experience='XXX' location='XXX'/> </friend_list> </query> </iq> */ char *data = wf_get_query_content ( msg ); #if 0 printf ( "\n\nDECODED:\n%s\n\n", data ); #endif //friend_list_empty(); unsigned int old_friends = session.profile.friends->length; unsigned int new_friends = 0; const char *m = strstr ( data, "<friend_list" ); const char *tmp = m + sizeof ( "<friend_list" ); while ( ( tmp = strstr ( tmp, "<friend" ) ) ) { new_friends++; tmp += sizeof ( "<friend" ); } if ( new_friends < old_friends ) friend_list_empty ( ); if ( m != NULL ) { m += sizeof ( "<friend_list" ); while ( ( m = strstr ( m, "<friend" ) ) ) { m += sizeof ( "<friend" ); char *jid = get_info ( m, "jid='", "'", NULL ); char *nick = get_info ( m, "nickname='", "'", NULL ); char *pid = get_info ( m, "profile_id='", "'", NULL ); int status = get_info_int ( m, "status='", "'", NULL ); int exp = get_info_int ( m, "experience='", "'", NULL ); if ( list_get ( session.profile.friends, nick ) ) friend_list_update ( jid, nick, pid, status, exp, "", "", "", "" ); else { if ( jid && *jid ) if ( !( status & ( STATUS_AFK | STATUS_PLAYING ) ) ) LOGPRINT ( "Friend: " KGRN BOLD "%s" KWHT "\n", nick ); else if ( status & STATUS_PLAYING ) LOGPRINT ( "Friend: " KMAG BOLD "%s" KWHT "\n", nick ); else LOGPRINT ( "Friend: " KYEL BOLD "%s" KWHT "\n", nick ); else LOGPRINT ( "Friend: " KCYN BOLD "%s" KWHT "\n", nick ); struct friend *f = friend_list_add ( jid, nick, pid, status, exp ); if ( f->jid ) xmpp_iq_peer_status_update ( f ); } free ( jid ); free ( nick ); free ( pid ); } }
static void xmpp_iq_get_master_servers_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer : <iq from='k01.warface' type='result'> <query xmlns='urn:cryonline:k01'> <get_master_servers> <masterservers> <server resource='pvp_pro_2' server_id='302' channel='pvp_pro' rank_group='all' load='0.590588' online='501' min_rank='13' max_rank='80' bootstrap=''> <load_stats> <load_stat type='quick_play' value='251'/> <load_stat type='survival' value='255'/> <load_stat type='pve' value='255'/> </load_stats> </server> ... </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type & XMPP_TYPE_ERROR) { free(a); return; } char *data = wf_get_query_content(msg); if (data == NULL) { free(a); return; } const char *m = data; struct list *masterservers = masterserver_list_new(); while ((m = strstr(m, "<server "))) { char *server = get_info(m, "<server ", ">", NULL); struct masterserver *ms = calloc(1, sizeof (struct masterserver)); ms->server_id = get_info_int(m, "server_id='", "'", NULL); ms->online = get_info_int(m, "online='", "'", NULL); ms->min_rank = get_info_int(m, "min_rank='", "'", NULL); ms->max_rank = get_info_int(m, "max_rank='", "'", NULL); ms->resource = get_info(m, "resource='", "'", NULL); ms->channel = get_info(m, "channel='", "'", NULL); ms->rank_group = get_info(m, "rank_group='", "'", NULL); ms->bootstrap = get_info(m, "bootstrap='", "'", NULL); ms->load = get_info_float(m, "load='", "'", NULL); list_add(masterservers, ms); free(server); ++m; } if (a->cb) a->cb(masterservers, a->args); else list_free(masterservers); free(data); free(a); }
static void xmpp_iq_join_channel_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer <iq from='masterserver@warface/pve_12' to='xxxxxx@warface/GameClient' type='result'> <query xmlns='urn:cryonline:k01'> <data query_name='join_channel' compressedData='...' originalSize='13480'/> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; char *data = wf_get_query_content(msg); if (type & XMPP_TYPE_ERROR) { fprintf(stderr, "Failed to join channel\nReason: "); int code = get_info_int(msg, "code='", "'", NULL); int custom_code = get_info_int(msg, "custom_code='", "'", NULL); switch (code) { case 1006: fprintf(stderr, "QoS limit reached\n"); break; case 503: fprintf(stderr, "Invalid channel (%s)\n", a->channel); break; case 8: switch (custom_code) { case 0: fprintf(stderr, "Invalid token (%s) or userid (%s)\n", session.active_token, session.online_id); break; case 1: fprintf(stderr, "Invalid profile_id (%s)\n", session.profile_id); break; case 2: fprintf(stderr, "Game version mismatch (%s)\n", game_version_get()); break; case 3: fprintf(stderr, "Banned\n"); break; case 5: fprintf(stderr, "Rank restricted\n"); break; default: fprintf(stderr, "Unknown code (%d)\n", custom_code); break; } break; default: fprintf(stderr, "Unknown\n"); break; } } else { /* Leave previous room if any */ xmpp_iq_gameroom_leave(); if (data != NULL) { session.experience = get_info_int(data, "experience='", "'", "EXPERIENCE"); if (a->channel != NULL) { free(session.channel); session.channel = strdup(a->channel); } char *m = data; while ((m = strstr(m, "<notif"))) { char *notif = get_info(m, "<notif", "</notif>", NULL); xmpp_iq_confirm_notification(notif); free(notif); ++m; } } /* Ask for today's missions list */ mission_list_update(NULL, NULL); /* Inform to k01 our status */ xmpp_iq_player_status(STATUS_ONLINE | STATUS_LOBBY); if (a->cb) a->cb(a->args); } free(data); free(a->channel); free(a); }
static void xmpp_iq_create_profile_cb(const char *msg, enum xmpp_msg_type type, void *args) { if (msg == NULL) return; if (type & XMPP_TYPE_ERROR) { const char *reason = NULL; int code = get_info_int(msg, "code='", "'", NULL); int custom_code = get_info_int(msg, "custom_code='", "'", NULL); switch (code) { case 1006: reason = "QoS limit reached"; break; case 503: reason = "Invalid channel"; break; case 8: switch (custom_code) { case 0: reason = "Invalid token or userid"; break; case 1: reason = "Invalid profile_id"; break; case 2: reason = "Game version mismatch"; break; case 3: reason = "Banned"; break; default: break; } break; default: break; } if (reason != NULL) eprintf("Failed to create profile (%s)\n", reason); else eprintf("Failed to create profile (%i:%i)\n", code, custom_code); return; } char *data = wf_get_query_content(msg); if (data == NULL) return; session.profile.id = get_info(data, "profile_id='", "'", "PROFILE ID"); session.profile.nickname = get_info(data, "nick='", "'", "NICKNAME"); #ifdef DBUS_API dbus_api_setup(); #endif /* Ask for today's missions list */ mission_list_update(NULL, NULL); free(data); }
static void _randombox_cb ( const char *msg, enum xmpp_msg_type type, void *args ) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <shop_buy_multiple_offer error_status="0"> <purchased_item> <exp name="exp_item_01" added="50" total="40014" offerId="9870"/> <profile_item name="flashbang" profile_item_id="xxxxx" offerId="9870" added_expiration="1 day" added_quantity="0" error_status="0"> <item id="xxxxx" name="flashbang" attached_to="0" config="dm=0;material=;pocket_index=3246082" slot="0" equipped="0" default="0" permanent="0" expired_confirmed="0" buy_time_utc="1429646487" expiration_time_utc="1449778407" seconds_left="172628"/> </profile_item> <exp name="exp_item_01" added="50" total="40064" offerId="9871"/> ... </purchased_item> <money game_money="AAA" cry_money="BBB" crown_money="CCC"/> </shop_buy_multiple_offer> </query> </iq> */ struct cmd_randombox_args_cb_t *randombox_args = (struct cmd_randombox_args_cb_t*) args; if ( type & XMPP_TYPE_ERROR ) { LOGPRINT ( KRED BOLD "Error while purchasing items\n" ); return; } char *data = wf_get_query_content ( msg ); if ( data != NULL ) { //printf ( "Answer: \n---------\n%s\n--------\n\n", data ); unsigned int error_code = get_info_int ( data, "error_status='", "'", NULL ); unsigned int money_left = get_info_int ( data, "game_money='", "'", NULL ); const char *m = strstr ( data, "<shop_buy_multiple_offer" ); if ( m != NULL && ( error_code == 1 || error_code == 0 ) ) { unsigned total_xp = 0; m += sizeof ( "<shop_buy_multiple_offer" ); do { const char *exp_s = strstr ( m, "<exp" ); const char *profile_item_s = strstr ( m, "<profile_item" ); if ( exp_s != NULL && ( profile_item_s == NULL || exp_s < profile_item_s ) ) { m = exp_s + sizeof ( "<exp" ); total_xp += get_info_int ( m, "added='", "'", NULL ); } else if ( profile_item_s != NULL ) { m = profile_item_s + sizeof ( "<profile_item" ); char *name = get_info ( m, "name='", "'", NULL ); char *expir = get_info ( m, "added_expiration='", "'", NULL ); char *quant = get_info ( m, "added_quantity='", "'", NULL ); LOGPRINT ( "%-20s %-10s %s\n", "ITEM", expir && expir[ 0 ] != '0' ? expir : quant, name ); if ( randombox_args->needed && strstr ( name, randombox_args->needed ) ) { LOGPRINT ( KGRN BOLD "%-20s %s\a\n" KRST KWHT, "GOT ITEM", name ); randombox_args->gotNeeded = 1; } free ( quant ); free ( expir ); free ( name ); } else { break; } } while ( 1 ); randombox_args->moneyLeft = money_left; randombox_args->xp += total_xp; LOGPRINT ( "%-20s " BOLD "%d\n", "MONEY LEFT", money_left ); if ( randombox_args->moneyLeft < randombox_args->stopMoney || randombox_args->gotNeeded ) { session.profile.money.game = randombox_args->moneyLeft; session.profile.experience += randombox_args->xp; LOGPRINT ( "%-20s " BOLD "%d\n", "TOTAL XP EARNED", randombox_args->xp ); free ( randombox_args->needed ); free ( randombox_args ); return; } char *offers = NULL; unsigned int i = 0; for ( ; i < 5; ++i ) { char *s; FORMAT ( s, "%s<offer id='%d'/>", offers ? offers : "", randombox_args->rid + i ); free ( offers ); offers = s; } t_uid id; idh_generate_unique_id ( &id ); idh_register ( &id, 0, _randombox_cb, randombox_args ); send_stream_format ( session.wfs, "<iq id='%s' to='masterserver@warface/%s' type='get'>" "<query xmlns='urn:cryonline:k01'>" "<shop_buy_multiple_offer supplier_id='1'>" "%s" "</shop_buy_multiple_offer>" "</query>" "</iq>", &id, session.online.channel, offers ); free ( offers ); } else { switch ( error_code ) { case 2: LOGPRINT ( KRED BOLD "Restricted purchase\n" ); break; default: break; } session.profile.money.game = randombox_args->moneyLeft; session.profile.experience += randombox_args->xp; LOGPRINT ( "%-20s " BOLD "%d\n", "TOTAL XP EARNED", randombox_args->xp ); free ( randombox_args->needed ); free ( randombox_args ); } } free ( data ); return; }
static void _randombox_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <shop_buy_multiple_offer error_status="0"> <purchased_item> <exp name="exp_item_01" added="50" total="40014" offerId="9870"/> <profile_item name="flashbang" profile_item_id="xxxxx" offerId="9870" added_expiration="1 day" added_quantity="0" error_status="0"> <item id="xxxxx" name="flashbang" attached_to="0" config="dm=0;material=;pocket_index=3246082" slot="0" equipped="0" default="0" permanent="0" expired_confirmed="0" buy_time_utc="1429646487" expiration_time_utc="1449778407" seconds_left="172628"/> </profile_item> <exp name="exp_item_01" added="50" total="xxxx" offerId="9871"/> <crown_money name='crown_money_item_01' added='100' total='xxxx'/> ... </purchased_item> <money game_money="AAA" cry_money="BBB" crown_money="CCC"/> </shop_buy_multiple_offer> </query> </iq> */ if (type & XMPP_TYPE_ERROR) { xprintf("Error while purshasing items\n"); return; } char *data = wf_get_query_content(msg); if (data != NULL) { unsigned int error_code = get_info_int(data, "error_status='", "'", NULL); unsigned int game_money_left = get_info_int(data, "game_money='", "'", NULL); unsigned int crown_money_left = get_info_int(data, "crown_money='", "'", NULL); unsigned int cry_money_left = get_info_int(data, "cry_money='", "'", NULL); const char *m = strstr(data, "<shop_buy_multiple_offer"); if (m != NULL && (error_code == 1 || error_code == 0)) { unsigned total_xp = 0; unsigned total_crown = 0; m += sizeof ("<shop_buy_multiple_offer"); do { const char *exp_s = strstr(m, "<exp"); const char *crown_s = strstr(m, "<crown_money"); const char *profile_item_s = strstr(m, "<profile_item"); if (exp_s != NULL && (profile_item_s == NULL || exp_s < profile_item_s) && (crown_s == NULL || exp_s < crown_s)) { m = exp_s + sizeof ("<exp"); total_xp += get_info_int(m, "added='", "'", NULL); } else if (crown_s != NULL && (profile_item_s == NULL || crown_s < profile_item_s) && (exp_s == NULL || crown_s < exp_s)) { m = crown_s + sizeof ("<crown_money"); total_crown += get_info_int(m, "added='", "'", NULL); } else if (profile_item_s != NULL) { m = profile_item_s + sizeof ("<profile_item"); char *name = get_info(m, "name='", "'", NULL); char *expir = get_info(m, "added_expiration='", "'", NULL); char *quant = get_info(m, "added_quantity='", "'", NULL); int perm = get_info_int(m, "permanent='", "'", NULL); xprintf("RB Item: %9s %s\n", expir && expir[0] != '0' ? expir : quant && quant[0] != '0' ? quant : perm ? "100%" : "Permanent", name); free(quant); free(expir); free(name); } else { break; } } while (1); if (total_xp != 0) xprintf("RB Item: %9u XP\n", total_xp); if (total_crown != 0) xprintf("RB Item: %9u crown\n", total_crown); session.profile.experience += total_xp; session.profile.money.game = game_money_left; session.profile.money.crown = crown_money_left; session.profile.money.cry = cry_money_left; xprintf("Money left: %9d WFD - %9d Crowns - %9d K\n", game_money_left, crown_money_left, cry_money_left); } else { switch (error_code) { case 1: xprintf("Not enough money\n"); break; case 2: xprintf("Restricted purshase\n"); break; case 3: xprintf("Out of store\n"); break; case 4: xprintf("Limit reached\n"); break; case 5: xprintf("Item not available\n"); break; default: xprintf("Error (code: %d)\n", error_code); break; } } } free(data); return; }
static void xmpp_iq_gameroom_open_cb(const char *msg, enum xmpp_msg_type type, void *args) { /* Answer : <iq to='masterserver@warface/pve_2' type='get'> <query xmlns='urn:cryonline:k01'> <data query_name='gameroom_open' compressedData='...' originalSize='42'/> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type & XMPP_TYPE_ERROR) { int code = get_info_int(msg, "code='", "'", NULL); int custom_code = get_info_int(msg, "custom_code='", "'", NULL); const char *reason = NULL; switch (code) { case 1006: reason = "QoS limit reached"; break; case 8: switch (custom_code) { case 0: /* Expired mission, update and try again */ if (++a->tries < 2) { struct mission *m = mission_list_get_by_key(a->mission_key); if (m != NULL) { a->mission_name = strdup(m->name); mission_list_update( _open_updated_list, args); return; } } reason = "Expired missions"; break; case 1: reason = "Invalid or expired mission"; break; case 12: reason = "Rank restricted"; break; case 21: reason = "Invalid room name"; break; default: break; } break; default: break; } if (reason != NULL) eprintf("Failed to open room (%s)\n", reason); else eprintf("Failed to open room (%i:%i)\n", code, custom_code); } else { char *data = wf_get_query_content(msg); if (data == NULL) { free(a); return; } /* Leave previous room if any */ if (session.gameroom.jid != NULL) { xmpp_presence(session.gameroom.jid, XMPP_PRESENCE_LEAVE, NULL, NULL); free(session.gameroom.group_id); session.gameroom.group_id = NULL; free(session.gameroom.jid); session.gameroom.jid = NULL; gameroom_sync_free(); } char *room = get_info(data, "room_id='", "'", "Room ID"); if (room != NULL) { /* Join XMPP room */ char *room_jid; FORMAT(room_jid, "*****@*****.**", session.online.channel, room); xmpp_presence(room_jid, XMPP_PRESENCE_JOIN, NULL, NULL); session.gameroom.jid = room_jid; /* Reset auto-ready */ session.gameroom.desired_status = GAMEROOM_READY; gameroom_sync_init(); gameroom_sync(data); status_set(STATUS_ONLINE | STATUS_ROOM); } if (a->fun != NULL) a->fun(room, a->args); free(room); free(data); } free(a->mission_name); a->mission_name = NULL; free(a->mission_key); a->mission_key = NULL; free(a); }
static void xmpp_iq_clan_members_updated_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='k01.warface' type='get'> <query xmlns='urn:cryonline:k01'> <clan_members_updated> <update profile_id='xxxx'> <clan_member_info nickname='xxxx' profile_id='xxxx' experience='xxxxx' clan_points='xxxx' invite_date='xxxx' clan_role='xxx' jid='xxxxx' status='xxxx'/> </update> </clan_members_updated> </query> </iq> or <iq from='k01.warface' type='get'> <query xmlns='urn:cryonline:k01'> <clan_members_updated> <update profile_id='xxxx'/> </clan_members_updated> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; const char *m = data; while ((m = strstr(m, "<update"))) { char *update = get_info(m, "<update", "</update>", NULL); if (update == NULL) update = get_info(m, "<update", "/>", NULL); if (update == NULL) { ++m; continue; } char *jid = get_info(update, "jid='", "'", NULL); char *nick = get_info(update, "nickname='", "'", NULL); char *pid = get_info(update, "profile_id='", "'", NULL); int status = get_info_int(update, "status='", "'", NULL); int exp = get_info_int(update, "experience='", "'", NULL); int cp = get_info_int(update, "clan_points='", "'", NULL); int cr = get_info_int(update, "clan_role='", "'", NULL); if (pid == NULL) { free(jid); free(pid); free(nick); free(update); ++m; continue; } /* If it's us */ if (0 == strcmp(pid, session.profile.id)) { session.profile.clan.points = cp; session.profile.clan.role = cr; } else { char *real_nick = NULL; if (nick == NULL) { struct clanmate *c = clanmate_list_get_by_pid(pid); if (c != NULL && c->nickname != NULL) real_nick = strdup(c->nickname); } else real_nick = strdup(nick); if (real_nick != NULL) { enum clan_update ret = clanmate_list_update(jid, real_nick, pid, status, exp, cp, cr); switch (ret) { case CLAN_UPDATE_JOINED: { char *s = LANG_FMT(notif_clan_joined, real_nick); xprintf("%s", s); free(s); break; } case CLAN_UPDATE_LEFT: { char *s = LANG_FMT(notif_clan_left, real_nick); xprintf("%s", s); free(s); break; } default: break; } } free(real_nick); } free(jid); free(nick); free(pid); free(update); ++m; } free(data); }
void xmpp_iq_sponsor_info_updated_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='masterserver@warface/xxx' type='get'> <query xmlns='urn:cryonline:k01'> <sponsor_info_updated sponsor_id='0' sponsor_points='864' total_sponsor_points='2064' next_unlock_item='smg07_shop'> <unlocked_items> <item name='xxx' .../> </unlocked_items> </sponsor_info_updated> </query> </iq> */ char *data = wf_get_query_content(msg); if (data == NULL) return; unsigned sponsor_id = get_info_int(data, "sponsor_id='", "'", NULL); unsigned points = get_info_int(data, "sponsor_points='", "'", NULL); unsigned total = get_info_int(data, "total_sponsor_points='", "'", NULL); char *next_item = get_info(data, "next_unlock_item='", "'", NULL); char *unlocked_items = get_info(data, "<unlocked_items>", "</unlocked_items>", NULL); if (unlocked_items != NULL) { const char *m = unlocked_items; while ((m = strstr(m, "<item")) != NULL) { char *item = get_info(m, "<item", "/>", NULL); char *item_name = get_info(item, "name='", "'", NULL); xprintf("%s: %s", LANG(notif_unlock_item), item_name); free(item_name); free(item); ++m; } } const char *sponsor = NULL; switch (sponsor_id) { case 0: sponsor = LANG(console_sponsor_weapon); break; case 1: sponsor = LANG(console_sponsor_outfit); break; case 2: sponsor = LANG(console_sponsor_equipment); break; default: break; } if (sponsor != NULL && sponsor[0]) { xprintf("%s: %u (+%u) - %s %s", sponsor, total, points, LANG(notif_unlocking), next_item); } else { xprintf("%s: %u (+%u) - %s", sponsor, total, points, LANG(notif_unlocking_done)); } free(unlocked_items); free(next_item); free(data); }
static void xmpp_iq_clan_info_cb ( const char *msg_id, const char *msg, void *args ) { char *data = wf_get_query_content ( msg ); //clanmate_list_empty(); unsigned int old_clanmates = session.clan.clanmates->length + 1; unsigned int new_clanmates = 0; /* Answer: <clan name="XXXXXXX" clan_id="xxx" description="..." creation_date="xxxx" master="xxxx" clan_points="xxxxx" members="xx" master_badge="xxxx" master_stripe="xxxx" master_mark="xxx" leaderboard_position="xx"> */ const char *m = strstr ( data, "<clan " ); if ( m != NULL ) { m += sizeof ( "<clan " ) - 1; session.clan.id = get_info_int ( m, "clan_id='", "'", NULL ); session.clan.name = get_info ( m, "name='", "'", NULL ); int old_leaderboard_position = session.clan.leaderboard_position; session.clan.leaderboard_position = get_info_int ( m, "leaderboard_position='", "'", NULL ); if ( old_leaderboard_position != session.clan.leaderboard_position ) LOGPRINT ( "%-20s " BOLD "%d\n", "CLAN RANK", session.clan.leaderboard_position ); const char *tmp = m; while ( ( tmp = strstr ( tmp, "<clan_member_info " ) ) ) { new_clanmates++; tmp += sizeof ( "<clan_member_info" ); } if ( new_clanmates < old_clanmates ) clanmate_list_empty ( ); /* Nodes: <clan_member_info nickname="xxxx" profile_id="xxx" experience="xxx" clan_points="xxx" invite_date="xxxxxxxxx" clan_role="3" jid="xxxx@warface/GameClient" status="1" /> */ while ( ( m = strstr ( m, "<clan_member_info " ) ) ) { m += sizeof ( "<clan_member_info " ); char *jid = get_info ( m, "jid='", "'", NULL ); char *nick = get_info ( m, "name='", "'", NULL ); char *pid = get_info ( m, "profile_id='", "'", NULL ); int status = get_info_int ( m, "status='", "'", NULL ); int exp = get_info_int ( m, "experience='", "'", NULL ); int cp = get_info_int ( m, "clan_points='", "'", NULL ); int cr = get_info_int ( m, "clan_role='", "'", NULL ); unsigned int invite_date = get_info_int ( m, "invite_date='", "'", NULL ); if ( strcmp ( session.profile.nickname, nick ) != 0 ) { if ( list_get ( session.clan.clanmates, nick ) ) clanmate_list_update ( jid, nick, pid, status, exp, cp, cr, invite_date, "", "", "", "" ); else { struct clanmate *c = clanmate_list_add ( jid, nick, pid, status, exp, cp, cr, invite_date ); if ( jid && *jid ) if ( !( status & ( STATUS_AFK | STATUS_PLAYING ) ) ) LOGPRINT ( "Clanmate: " KGRN BOLD "%s" KWHT "\n", nick ); else if ( status & STATUS_PLAYING ) LOGPRINT ( "Clanmate: " KMAG BOLD "%s" KWHT "\n", nick ); else LOGPRINT ( "Clanmate: " KYEL BOLD "%s" KWHT "\n", nick ); else LOGPRINT ( "Clanmate: " KCYN BOLD "%s" KWHT "\n", nick ); if ( c->jid ) xmpp_iq_peer_clan_member_update ( c ); } } else { session.clan.points = cp; session.clan.role = cr; session.clan.joined = invite_date; } free ( jid ); free ( nick ); free ( pid ); } } if ( old_clanmates != new_clanmates ) LOGPRINT ( "Clan member count: " KWHT BOLD "%u/50\n", new_clanmates ); free ( data ); }