static void _parse_abuse_manager_config(struct game_config *config, const char *elt) { config->abuse.limits.reports_per_day = get_info_int(elt, "reports_per_day='", "'", NULL); config->abuse.limits.reports_per_player = get_info_int(elt, "reports_per_player='", "'", NULL); config->abuse.report_types = list_new((f_list_cmp) abuse_report_type_cmp, (f_list_free) abuse_report_type_free); const char *m = elt; while ((m = strstr(m, "<report_type "))) { char *report_type = get_info(m, "<report_type ", "/>", NULL); struct abuse_report_type *type = calloc(1, sizeof (struct abuse_report_type)); type->name = get_info(report_type, "name='", "'", NULL); type->message = get_info(report_type, "message='", "'", NULL); list_add(config->abuse.report_types, type); free(report_type); ++m; } }
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 _parse_ui_menu_unlock(struct game_config *config, const char *elt) { config->ui_menu_unlock.enabled = get_info_int(elt, "enabled='", "'", NULL); config->ui_menu_unlock.unlocks = list_new((f_list_cmp) ui_menu_unlock_unlock_cmp, (f_list_free) ui_menu_unlock_unlock_free); const char *m = elt; while ((m = strstr(m, "<unlock "))) { char *unlock = get_info(m, "<unlock ", "/>", NULL); struct ui_menu_unlock_unlock *u = calloc(1, sizeof (struct ui_menu_unlock_unlock)); u->screen = get_info(unlock, "screen='", "'", NULL); u->option = get_info(elt, "option='", "'", NULL); u->rank = get_info_int(elt, "rank='", "'", NULL); list_add(config->ui_menu_unlock.unlocks, u); free(unlock); ++m; } }
static void _parse_login_bonus(struct login_bonus_config *login_bonus, const char *elt) { login_bonus->enabled = get_info_int(elt, "enabled='", "'", NULL); login_bonus->use_notification = get_info_int(elt, "use_notification='", "'", NULL); login_bonus->schedule = get_info(elt, "schedule='", "'", NULL); login_bonus->expiration = get_info(elt, "expiration='", "'", NULL); login_bonus->streaks = list_new((f_list_cmp) login_streak_cmp, (f_list_free) login_streak_free); unsigned int j = 0; const char *m2 = elt; while ((m2 = strstr(m2, "<streak>"))) { char *streak_node = get_info(m2, "<streak>", "</streak>", NULL); struct login_streak *streak = calloc(1, sizeof (struct login_streak)); streak->id = j++; streak->rewards = list_new((f_list_cmp) login_reward_cmp, (f_list_free) login_reward_free); unsigned int i = 0; const char *m = streak_node; while ((m = strstr(m, "<reward "))) { char *reward_node = get_info(m, "<reward ", "/>", NULL); struct login_reward *reward = calloc(1, sizeof (struct login_reward)); reward->id = i++; reward->name = get_info(reward_node, "name='", "'", NULL); list_add(streak->rewards, reward); free(reward_node); ++m; } list_add(login_bonus->streaks, streak); free(streak_node); ++m2; } }
static void _parse_vote(struct vote_config *vote, const char *elt) { vote->can_be_started_after_sec = get_info_int(elt, "can_be_started_after_sec='", "'", NULL); vote->cooldown_sec = get_info_int(elt, "cooldown_sec='", "'", NULL); vote->timeout_sec = get_info_int(elt, "timeout_sec='", "'", NULL); vote->success_threshold = get_info_float(elt, "success_threshold='", "'", NULL); }
void xmpp_iq_confirm_notification(const char *notif) { char *notif_id = get_info(notif, "id='", "'", NULL); enum e_notif_type notif_type = get_info_int(notif, "type='", "'", NULL); switch (notif_type) { /* Confirm consecutive logins */ case NOTIF_CONS_LOGIN: puts("Getting consecutive reward"); /* Accept any friend requests */ case NOTIF_FRIEND_REQUEST: send_stream_format(session.wfs, "<iq to='masterserver@warface/%s' type='get'>" " <query xmlns='urn:cryonline:k01'>" " <confirm_notification>" " <notif id='%s' type='%d'>" " <confirmation result='0' status='%d'" " location=''/>" " </notif>" " </confirm_notification>" " </query>" "</iq>", session.channel, notif_id, notif_type, session.status); break; /* Old fashion peer_status_update */ case NOTIF_STATUS_UPDATE: { char *jid = get_info(notif, "jid='", "'", NULL); char *nick = get_info(notif, "nickname='", "'", NULL); char *pid = get_info(notif, "profile_id='", "'", NULL); int status = get_info_int(notif, "status='", "'", NULL); int exp = get_info_int(notif, "experience='", "'", NULL); if (status <= STATUS_OFFLINE) jid = NULL; friend_list_add(jid, nick, pid, status, exp); xmpp_iq_peer_status_update(jid); free(jid); free(nick); free(pid); } break; default: break; } free(notif_id); }
static void _parse_rating_curve(struct game_config *config, const char *elt) { config->rating.curve.step = get_info_int(elt, "step='", "'", NULL); config->rating.curve.leave_penalty = get_info_int(elt, "leave_penalty='", "'", NULL); config->rating.curve.top_rating_capacity = get_info_int(elt, "top_rating_capacity='", "'", NULL); { char *win_streak_node = get_info(elt, "<win_streak", "/>", NULL); if (win_streak_node != NULL) { config->rating.curve.win_streak.enabled = get_info_int(win_streak_node, "enabled='", "'", NULL); config->rating.curve.win_streak.bonus_amount = get_info_int(win_streak_node, "bonus_amount='", "'", NULL); config->rating.curve.win_streak.start_from_streak = get_info_int(win_streak_node, "start_from_streak='", "'", NULL); config->rating.curve.win_streak.apply_below_rating = get_info_int(win_streak_node, "apply_below_rating='", "'", NULL); } free(win_streak_node); } config->rating.curve.steps = list_new((f_list_cmp) rating_curve_step_cmp, (f_list_free) rating_curve_step_free); const char *m = elt; while ((m = strstr(m, "<rating "))) { char *rating = get_info(m, "<rating ", "/>", NULL); struct rating_curve_step *step = calloc(1, sizeof (struct rating_curve_step)); step->points_required = get_info_int(rating, "points_required='", "'", NULL); step->adjustment = get_info_int(rating, "adjustment='", "'", NULL); step->icon = get_info(rating, "icon='", "'", NULL); step->description = get_info(rating, "description='", "'", NULL); list_add(config->rating.curve.steps, step); free(rating); ++m; } }
int gameroom_parse(struct gameroom *gr, const char *data) { int ret = 0; gr->room_type = get_info_int(data, "room_type='", "'", NULL); free(gr->room_id); gr->room_id = get_info(data, "room_id='", "'", NULL); #define X(Name, Offset, Field) { \ char *n = NULL; \ n = get_info(data, "<" #Field, "</" #Field ">", NULL); \ n = n ? n : get_info(data, "<" #Field " ", "/>", NULL); \ ret |= gameroom_sync_node((s_gr_sync *) &gr->Field, \ (f_sync_func) _sync_ ## Field, \ n); \ free(n); \ } SYNC_LIST; #undef X return ret; }
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 _parse_regions(struct game_config *config, const char *elt) { { char *distances_node = get_info(elt, "<distances>", "</distances>", NULL); if (distances_node != NULL) { config->regions.distances = list_new((f_list_cmp) region_distance_cmp, (f_list_free) region_distance_free); const char *m = distances_node; while ((m = strstr(m, "<distance "))) { char *distance_node = get_info(m, "<distance ", "/>", NULL); struct region_distance *d = calloc(1, sizeof (struct region_distance)); d->from = get_info(distance_node, "from='", "'", NULL); d->to = get_info(distance_node, "to='", "'", NULL); d->value = get_info_int(distance_node, "value='", "'", NULL); list_add(config->regions.distances, d); ++m; } } } }
static void cmd_whois_cb(const char *info, void *args) { struct cb_args *a = (struct cb_args *) args; if (info == NULL) { if (a->nick_to == NULL || a->jid_to == NULL) printf("No such user connected\n"); else xmpp_send_message(a->nick_to, a->jid_to, "I don't know that guy..."); free(a->nick_to); free(a->jid_to); free(a); } else { a->status = get_info_int(info, "status='", "'", NULL); a->ip = get_info(info, "ip_address='", "'", NULL); pthread_t thread_gl; if (pthread_create(&thread_gl, NULL, thread_get_geoloc, args) == -1) perror("pthread_create"); pthread_detach(thread_gl); } }
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_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 _parse_profile_progression_config(struct game_config *config, const char *elt) { config->profile_progression.enabled = get_info_int(elt, "enabled='", "'", NULL); config->profile_progression.events = list_new((f_list_cmp) profile_progression_event_cmp, (f_list_free) profile_progression_event_free); unsigned int i = 0; const char *end = strstr(elt, "</profile_progression_config>"); const char *m = elt + 1; while ((m = strstr(m, "<")) && m < end) { char *event_node = get_info(m, "<", "/>", NULL); struct profile_progression_event *event = calloc(1, sizeof (struct profile_progression_event)); event->id = i++; event->silent = get_info_int(event_node, "silent='", "'", NULL); event->rank_reached = get_info_int(event_node, "rank_reached='", "'", NULL); event->max_value = get_info_int(event_node, "max_value='", "'", NULL); event->pass_value = get_info_int(event_node, "pass_value='", "'", NULL); event->type = get_info(event_node, "type='", "'", NULL); event->tutorial_passed = get_info(event_node, "tutorial_passed='", "'", NULL); event->unlock_class = get_info(event_node, "unlock_class='", "'", NULL); event->special_reward = get_info(event_node, "special_reward='", "'", NULL); list_add(config->profile_progression.events, event); m += strlen(event_node); free(event_node); } }
static void xmpp_iq_profile_info_get_status_cb(const char *msg, void *args) { /* Answer: <iq from='k01.warface' type='result'> <query xmlns='urn:cryonline:k01'> <profile_info_get_status nickname='xxxx'> <profile_info> <info nickname='xxxx' online_id='xxxx@warface/GameClient' status='33' profile_id='xxx' user_id='xxxxx' rank='xx' tags='' ip_address='xxx.xxx.xxx.xxx' login_time='xxxxxxxxxxx'/> </profile_info> </profile_info_get_status> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (strstr(msg, "type='result'") == NULL || a->nick_to == NULL || a->jid_to == NULL) { free(a->nick_to); free(a->jid_to); free(a); } char *info = get_info(msg, "<info", "/>", NULL); if (info == NULL) { xmpp_send_message(session.wfs, session.nickname, session.jid, a->nick_to, a->jid_to, "I don't know that guy...", NULL); } else { a->status = get_info_int(info, "status='", "'", NULL); a->ip = get_info(info, "ip_address='", "'", NULL); pthread_t thread_gl; if (pthread_create(&thread_gl, NULL, thread_get_geoloc, args) == -1) perror("pthread_create"); pthread_detach(thread_gl); } free(info); }
static void cmd_stats_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_newbie_1' server_id='101' channel='pvp_newbie' rank_group='all' load='0.071765' online='61' min_rank='1' max_rank='12' bootstrap=''> <load_stats> <load_stat type='quick_play' value='240'/> <load_stat type='survival' value='255'/> <load_stat type='pve' value='255'/> </load_stats> </server> <server resource='pvp_pro_4' ... </masterservers> </get_master_servers> </query> </iq> */ struct cb_args *a = (struct cb_args *) args; if (type ^ XMPP_TYPE_ERROR) { const char *m = msg; while ((m = strstr(m, "<server"))) { char *server = get_info(m, "<server", "</server>", NULL); char *resource = get_info(server, "resource='", "'", NULL); int online = get_info_int(server, "online='", "'", NULL); if (a->cb && resource != NULL) a->cb(resource, online, a->args); free(resource); free(server); ++m; } } if (a->cb) a->cb(NULL, 0, a->args); free(a); }
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_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); }
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 inline int gameroom_sync_node(s_gr_sync *local, f_sync_func sync, const char *node) { if (node == NULL) return 0; unsigned int revision = get_info_int(node, "revision='", "'", NULL); if (revision > local->revision) { local->revision = revision; sync(local, node); return local->type; } return 0; }
static void xmpp_iq_gameroom_loosemaster_cb(const char *msg_id, const char *msg, void *args) { /* Answer: <iq from='masterserver@warface/pvp_pro_4' type='get'> <query xmlns='urn:cryonline:k01'> <gameroom_loosemaster time='10'/> </query> </iq> */ unsigned int time = get_info_int(msg, "time='", "'", "Start counter"); if (time <= 10) { xmpp_iq_gameroom_askserver(NULL, NULL); } }
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_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_gameroom_quickplay_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'> <gameroom_quickplay/> </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 1: /* 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( _quickplay_updated_list, args); return; } } reason = "Expired mission"; break; case 12: reason = "Invalid mission"; break; case 27: reason = "Ranked season over"; break; default: break; } break; default: break; } if (reason != NULL) eprintf("Failed to open quickplay room (%s)\n", reason); else eprintf("Failed to open quickplay room (%i:%i)\n", code, custom_code); } else { if (a->cb) a->cb(a->args); } free(a->mission_key); a->mission_key = NULL; free(a->mission_name); a->mission_name = NULL; free(a->game_mode); a->game_mode = NULL; free(a->uid); a->uid = NULL; free(a); }
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_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); }