//Disconnect the player out of the game, simple packet //packet.w AID.L WHY.B 2+4+1 = 7byte int chrif_disconnectplayer(int fd) { struct map_session_data* sd; sd = map_id2sd(RFIFOL(fd, 2)); if(sd == NULL) return -1; if (!sd->fd) { //No connection if (sd->state.autotrade) map_quit(sd); //Remove it. //Else we don't remove it because the char should have a timer to remove the player because it force-quit before, //and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex] return 0; } switch(RFIFOB(fd, 6)) { case 1: clif_authfail_fd(sd->fd, 1); break; //server closed case 2: clif_authfail_fd(sd->fd, 2); break; //someone else logged in case 3: clif_authfail_fd(sd->fd, 4); break; //server overpopulated case 4: clif_authfail_fd(sd->fd, 10); break; //out of available time paid for case 5: clif_authfail_fd(sd->fd, 15); break; //forced to dc by gm } return 0; }
// client authentication failed void chrif_authfail(int fd) { int account_id; int char_id; uint32 login_id1; char sex; uint32 ip; struct auth_node* node; account_id = RFIFOL(fd,2); char_id = RFIFOL(fd,6); login_id1 = RFIFOL(fd,10); sex = RFIFOB(fd,14); ip = ntohl(RFIFOL(fd,15)); node = chrif_search(account_id); if( node != NULL && node->account_id == account_id && node->char_id == char_id && node->login_id1 == login_id1 && node->sex == sex && node->state == ST_LOGIN ) {// found a match clif_authfail_fd(node->fd, 0); chrif_auth_delete(account_id, char_id, ST_LOGIN); } }
static int chrif_reconnect(DBKey key,void *data,va_list ap) { struct auth_node *node=(struct auth_node*)data; switch (node->state) { case ST_LOGIN: if (node->sd && node->char_dat == NULL) { //Since there is no way to request the char auth, make it fail. pc_authfail(node->sd); chrif_char_offline_nsd(node->account_id, node->char_id); chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN); } break; case ST_LOGOUT: //Re-send final save chrif_save(node->sd, 1); break; case ST_MAPCHANGE: { //Re-send map-change request. struct map_session_data *sd = node->sd; uint32 ip; uint16 port; if(map_mapname2ipport(sd->mapindex,&ip,&port)==0) chrif_changemapserver(sd, ip, port); else //too much lag/timeout is the closest explanation for this error. clif_authfail_fd(sd->fd, 3); break; } } return 0; }
// request to move a character between mapservers int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) { nullpo_retr(-1, sd); if (other_mapserver_count < 1) { //No other map servers are online! clif_authfail_fd(sd->fd, 0); return -1; } chrif_check(-1); WFIFOHEAD(char_fd,35); WFIFOW(char_fd, 0) = 0x2b05; WFIFOL(char_fd, 2) = sd->bl.id; WFIFOL(char_fd, 6) = sd->login_id1; WFIFOL(char_fd,10) = sd->login_id2; WFIFOL(char_fd,14) = sd->status.char_id; WFIFOW(char_fd,18) = sd->mapindex; WFIFOW(char_fd,20) = sd->bl.x; WFIFOW(char_fd,22) = sd->bl.y; WFIFOL(char_fd,24) = htonl(ip); WFIFOW(char_fd,28) = htons(port); WFIFOB(char_fd,30) = sd->status.sex; WFIFOL(char_fd,31) = 0; // sd's IP, not used anymore WFIFOSET(char_fd,35); return 0; }
/// map-server change request acknowledgement (positive or negative) /// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <x>.W <y>.W <ip>.L <port>.W int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { struct auth_node *node; if (!(node=chrif_auth_check(account_id, char_id, ST_MAPCHANGE))) return -1; if (!login_id1) { ShowError("map server change failed.\n"); clif_authfail_fd(node->fd, 0); } else clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port)); //Player has been saved already, remove him from memory. [Skotlex] chrif_auth_delete(account_id, char_id, ST_MAPCHANGE); return 0; }
int chrif_changesex(struct map_session_data *sd) { chrif_check(-1); WFIFOHEAD(char_fd,44); WFIFOW(char_fd,0) = 0x2b0e; WFIFOL(char_fd,2) = sd->status.account_id; safestrncpy((char*)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH); WFIFOW(char_fd,30) = 5; WFIFOSET(char_fd,44); clif_displaymessage(sd->fd, "Need disconnection to perform change-sex request..."); if (sd->fd) clif_authfail_fd(sd->fd, 15); else map_quit(sd); return 0; }
int chrif_changesex(struct map_session_data *sd) { chrif_check(-1); WFIFOHEAD(char_fd,44); WFIFOW(char_fd,0) = 0x2b0e; WFIFOL(char_fd,2) = sd->status.account_id; safestrncpy((char*)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH); WFIFOW(char_fd,30) = 5; WFIFOSET(char_fd,44); clif_displaymessage(sd->fd, "Necess�rio desconectar para realizar a mudan�a de sexo..."); if (sd->fd) clif_authfail_fd(sd->fd, 15); else map_quit(sd); return 0; }
/// map-server change request acknowledgement (positive or negative) /// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <x>.W <y>.W <ip>.L <port>.W int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { struct map_session_data *sd; sd = map_id2sd(account_id); if (sd == NULL || sd->status.char_id != char_id) return -1; if (login_id1 == 1) { if (battle_config.error_log) ShowError("map server change failed.\n"); clif_authfail_fd(sd->fd, 0); return 0; } clif_changemapserver(sd, map_index, x, y, ntohl(ip), ntohs(port)); //Player has been saved already, remove him from memory. [Skotlex] map_quit(sd); map_quit_ack(sd); return 0; }
// client authentication failed void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used (but is available) */ int account_id, char_id; uint32 login_id1; char sex; struct auth_node* node; account_id = RFIFOL(fd,2); char_id = RFIFOL(fd,6); login_id1 = RFIFOL(fd,10); sex = RFIFOB(fd,14); node = chrif_search(account_id); if( node != NULL && node->account_id == account_id && node->char_id == char_id && node->login_id1 == login_id1 && node->sex == sex && node->state == ST_LOGIN ) {// found a match clif_authfail_fd(node->fd, 0); chrif_auth_delete(account_id, char_id, ST_LOGIN); } }
void _FASTCALL harmony_action_request(int fd, int task, int id, intptr data) { TBL_PC *sd; if (fd == 0) { harmony_action_request_global(task, id, data); return; } switch (task) { case HARMTASK_PACKET: memcpy(WFIFOP(fd, 0), (const void*)data, id); //ShowInfo("Sending %d bytes to session #%d (%x)\n", id, fd, WFIFOW(fd, 0)); WFIFOSET(fd, id); return; } sd = (TBL_PC *)session[fd]->session_data; if (!sd) return; switch (task) { case HARMTASK_DC: ShowInfo("-- Harmony requested disconnect.\n"); set_eof(fd); break; case HARMTASK_KICK: ShowInfo("-- Harmony requested kick.\n"); if (id == 99) set_eof(fd); else clif_authfail_fd(fd, id); break; case HARMTASK_JAIL: { char msg[64]; snprintf(msg, sizeof(msg)-1, "@jail %s", sd->status.name); is_atcommand(0, sd, msg, 0); } break; case HARMTASK_BAN: harmony_ban(sd->status.account_id, id); break; case HARMTASK_ATCMD: is_atcommand(fd, sd, (const char*)data, 0); break; case HARMTASK_MSG: clif_displaymessage(fd, (const char*)data); break; case HARMTASK_IS_ACTIVE: *(int32*)data = (sd->bl.prev == NULL || sd->invincible_timer != INVALID_TIMER) ? 0 : 1; break; case HARMTASK_GET_ID: switch (id) { case HARMID_AID: *(int*)data = sd->status.account_id; break; case HARMID_GID: *(int*)data = sd->status.char_id; break; case HARMID_GDID: *(int*)data = sd->status.guild_id; break; case HARMID_PID: *(int*)data = sd->status.party_id; break; case HARMID_CLASS: *(short*)data = sd->status.class_; break; case HARMID_GM: #if HARMSW == HARMSW_RATHENA_GROUP *(int*)data = pc_group_id2level(sd->group_id); #else *(int*)data = pc_isGM(sd); #endif break; default: ShowError("Harmony requested unknown ID! (ID=%d)\n", id); ShowError("This indicates that you are running an incompatible version.\n"); break; } break; case HARMTASK_SCRIPT: { struct npc_data* nd = npc_name2id((const char*)data); if (nd) { run_script(nd->u.scr.script, 0, sd->bl.id, fake_nd->bl.id); } else { ShowError("A Harmony action chain tried to execute non-existing script '%s'\n", data); } } break; default: ShowError("Harmony requested unknown action! (ID=%d)\n", task); ShowError("This indicates that you are running an incompatible version.\n"); break; } }