Index: src/char/char.c =================================================================== --- src/char/char.c (revision 16828) +++ src/char/char.c (working copy) @@ -2809,7 +2809,7 @@ break; case 0x2b02: // req char selection - if( RFIFOREST(fd) < 18 ) + if( RFIFOREST(fd) < 19 ) return 0; { struct auth_node* node; @@ -2818,9 +2818,10 @@ uint32 login_id1 = RFIFOL(fd,6); uint32 login_id2 = RFIFOL(fd,10); uint32 ip = RFIFOL(fd,14); - RFIFOSKIP(fd,18); - - if( runflag != CHARSERVER_ST_RUNNING ) + uint8 group_id = RFIFOB(fd,18); + RFIFOSKIP(fd,19); + + if( runflag != CHARSERVER_ST_RUNNING && (runflag != CHARSERVER_ST_MAINTENANCE || group_id != 99) ) { WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x2b03; @@ -2873,7 +2874,7 @@ char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14)); } - if( runflag == CHARSERVER_ST_RUNNING && + if( (runflag == CHARSERVER_ST_RUNNING || runflag == CHARSERVER_ST_MAINTENANCE) && session_isActive(map_fd) && char_data ) { //Send the map server the auth of this player. @@ -3237,7 +3238,7 @@ mmo_char_fromsql(char_id, &char_dat, true); cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id); } - if( runflag == CHARSERVER_ST_RUNNING && + if( (runflag == CHARSERVER_ST_RUNNING || (runflag == CHARSERVER_ST_MAINTENANCE && node->group_id == 99)) && cd != NULL && node != NULL && node->account_id == account_id && @@ -3284,6 +3285,19 @@ ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip)); RFIFOSKIP(fd,6); break; + + case 0x2737: // is it maintenance? + if (RFIFOB(fd, 2) == CHARSERVER_ST_MAINTENANCE) { + //yezzz it iss + runflag = CHARSERVER_ST_MAINTENANCE; + //ShowInfo("Maintenance: On\n"); + } else { + if (runflag == CHARSERVER_ST_MAINTENANCE) { + runflag = CHARSERVER_ST_RUNNING; + //ShowInfo("Maintenance: Off\n"); + } + } RFIFOSKIP(fd, 3); + break; case 0x3008: if( RFIFOREST(fd) < RFIFOW(fd,4) ) @@ -3677,7 +3691,7 @@ WFIFOL(fd,0) = account_id; WFIFOSET(fd,4); - if( runflag != CHARSERVER_ST_RUNNING ) + if( runflag != CHARSERVER_ST_RUNNING && runflag != CHARSERVER_ST_MAINTENANCE ) { WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x6c; @@ -3700,6 +3714,27 @@ else {// authentication not found (coming from login server) if (login_fd > 0) { // don't send request if no login-server + if (runflag == CHARSERVER_ST_MAINTENANCE) { + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `group_id` FROM `login` WHERE `account_id` = %d", account_id) ) { + Sql_ShowDebug(sql_handle); + break; + } else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) { + char* data; + Sql_GetData(sql_handle, 0, &data, NULL); + Sql_FreeResult(sql_handle); + if (atoi(data) != 99) { + //Kick everyone except Admin(99) + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0; + WFIFOSET(fd,3); + break; + } + } else { + Sql_FreeResult(sql_handle); + break; + } + } WFIFOHEAD(login_fd,23); WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account WFIFOL(login_fd,2) = sd->account_id; Index: src/char/char.h =================================================================== --- src/char/char.h (revision 16828) +++ src/char/char.h (working copy) @@ -10,7 +10,8 @@ { CHARSERVER_ST_RUNNING = CORE_ST_LAST, CHARSERVER_ST_SHUTDOWN, - CHARSERVER_ST_LAST + CHARSERVER_ST_LAST, + CHARSERVER_ST_MAINTENANCE }; struct mmo_charstatus; Index: src/map/atcommand.c =================================================================== --- src/map/atcommand.c (revision 16828) +++ src/map/atcommand.c (working copy) @@ -8817,6 +8817,54 @@ #undef MC_CART_MDFY } +/*========================================== + * @maintenance commands [FE] + *------------------------------------------*/ +ACMD_FUNC(maintenance) { + nullpo_retr(-1, sd); + + if (message && *message) { + if(strcmpi(message, "on") == 0) { + if(runflag == MAPSERVER_ST_MAINTENANCE) { + clif->message(fd, "Server already in maintenance"); + } else { + struct map_session_data* pl_sd; + struct s_mapiterator* iter; + + iter = mapit_getallusers(); + for (pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter)) { + if (pc_get_group_level(pl_sd) != 99) { // Only Admin(99) that will stay in maintenance + clif->GM_kick(NULL, pl_sd); + } + } + mapit_free(iter); + + runflag = MAPSERVER_ST_MAINTENANCE; //Activate maintenance, disable all player except Admin to login + chrif_maintenis(MAPSERVER_ST_MAINTENANCE); + //ShowInfo("Maintenance: On\n"); + clif->message(fd, "Maintenance: On"); + } + } else if(strcmpi(message, "off") == 0) { + if(runflag == MAPSERVER_ST_MAINTENANCE) { + runflag = MAPSERVER_ST_RUNNING; //Deactivate maintenance + chrif_maintenis(MAPSERVER_ST_RUNNING); + //ShowInfo("Maintenance: Off\n"); + clif->message(fd, "Maintenance: Off"); + } else { + clif->message(fd, "Server is not in maintenance"); + } + } else { + clif->message(fd, "Usage: @maintenance "); + return -1; + } + } else { + clif->message(fd, "Usage: @maintenance "); + return -1; + } + + return 0; +} + /** * Fills the reference of available commands in atcommand DBMap **/ @@ -9071,7 +9119,8 @@ ACMD_DEF2("rmvperm", addperm), ACMD_DEF(unloadnpcfile), ACMD_DEF(cart), - ACMD_DEF(mount2) + ACMD_DEF(mount2), + ACMD_DEF(maintenance) }; AtCommandInfo* atcommand; int i; Index: src/map/chrif.c =================================================================== --- src/map/chrif.c (revision 16828) +++ src/map/chrif.c (working copy) @@ -578,6 +578,17 @@ chrif_sd_to_auth(sd, ST_LOGIN); } +//Tell char-server that map-server is in maintenance +void chrif_maintenis(int flag) +{ + if (!chrif_isconnected()) + return; + WFIFOHEAD(char_fd, 3); + WFIFOW(char_fd, 0) = 0x2737; + WFIFOB(char_fd, 2) = flag; + WFIFOSET(char_fd, 3); +} + /*========================================== * Auth confirmation ack *------------------------------------------*/ @@ -631,11 +642,11 @@ } sd = node->sd; - if( runflag == MAPSERVER_ST_RUNNING && + if( (runflag == MAPSERVER_ST_RUNNING || runflag == MAPSERVER_ST_MAINTENANCE) && node->char_dat == NULL && node->account_id == account_id && node->char_id == char_id && - node->login_id1 == login_id1 ) + node->login_id1 == login_id1) { //Auth Ok if (pc_authok(sd, login_id2, expiration_time, group_id, status, changing_mapservers)) return; @@ -718,13 +729,14 @@ return -1; chrif_check(-1); - WFIFOHEAD(char_fd,18); + WFIFOHEAD(char_fd,19); WFIFOW(char_fd, 0) = 0x2b02; 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) = htonl(s_ip); - WFIFOSET(char_fd,18); + WFIFOB(char_fd,18) = sd->group_id; + WFIFOSET(char_fd,19); return 0; } Index: src/map/chrif.h =================================================================== --- src/map/chrif.h (revision 16828) +++ src/map/chrif.h (working copy) @@ -57,6 +57,7 @@ int chrif_changesex(struct map_session_data *sd); int chrif_chardisconnect(struct map_session_data *sd); int chrif_divorce(int partner_id1, int partner_id2); +void chrif_maintenis(int flag); //[FE] int chrif_removefriend(int char_id, int friend_id); void chrif_send_report(char* buf, int len); Index: src/map/clif.c =================================================================== --- src/map/clif.c (revision 16828) +++ src/map/clif.c (working copy) @@ -9035,7 +9035,7 @@ return; } - if( runflag != MAPSERVER_ST_RUNNING ) + if( runflag != MAPSERVER_ST_RUNNING && runflag != MAPSERVER_ST_MAINTENANCE ) {// not allowed clif->authfail_fd(fd,1);// server closed return; Index: src/map/map.h =================================================================== --- src/map/map.h (revision 16828) +++ src/map/map.h (working copy) @@ -24,7 +24,8 @@ { MAPSERVER_ST_RUNNING = CORE_ST_LAST, MAPSERVER_ST_SHUTDOWN, - MAPSERVER_ST_LAST + MAPSERVER_ST_LAST, + MAPSERVER_ST_MAINTENANCE };