diff --git a/conf/char-server.conf b/conf/char-server.conf index b2120471c91..a7f26daaa69 100644 --- a/conf/char-server.conf +++ b/conf/char-server.conf @@ -65,7 +65,10 @@ console_silent: 0 // No functional side effects at the moment. // Displayed next to the server name in the client. // 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P -char_maintenance: 0 +char_server_type: 0 + +// Minimum Group ID to join char server when it is on char_server_type 1 (maintenance) +char_maintenance_min_group_id: 99 // Enable or disable creation of new characters. // Now it is actually supported [Kevin] diff --git a/src/char/char.c b/src/char/char.c index ce4fcbe53c2..77d9f521793 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -105,7 +105,8 @@ uint32 char_ip = 0; char bind_ip_str[128]; uint32 bind_ip = INADDR_ANY; uint16 char_port = 6121; -int char_maintenance = 0; +int char_server_type = 0; +int char_maintenance_min_group_id = 0; bool char_new = true; int char_new_display = 0; @@ -2226,7 +2227,7 @@ int parse_fromlogin(int fd) { // acknowledgement of account authentication request case 0x2713: - if (RFIFOREST(fd) < 25) + if (RFIFOREST(fd) < 29) return 0; { int account_id = RFIFOL(fd,2); @@ -2237,7 +2238,8 @@ int parse_fromlogin(int fd) { int request_id = RFIFOL(fd,16); uint32 version = RFIFOL(fd,20); uint8 clienttype = RFIFOB(fd,24); - RFIFOSKIP(fd,25); + int group_id = RFIFOL(fd,25); + RFIFOSKIP(fd,29); if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) @@ -2245,17 +2247,24 @@ int parse_fromlogin(int fd) { int client_fd = request_id; sd->version = version; sd->clienttype = clienttype; - switch( result ) - { - case 0:// ok - char_auth_ok(client_fd, sd); - break; - case 1:// auth failed - WFIFOHEAD(client_fd,3); - WFIFOW(client_fd,0) = 0x6c; - WFIFOB(client_fd,2) = 0;// rejected from server - WFIFOSET(client_fd,3); - break; + switch( result ) { + case 0:// ok + /* restrictions apply */ + if( char_server_type == CST_MAINTENANCE && group_id < char_maintenance_min_group_id ) { + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; + } + char_auth_ok(client_fd, sd); + break; + case 1:// auth failed + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; } } } @@ -3889,6 +3898,14 @@ int parse_char(int fd) node->login_id2 == login_id2 /*&& node->ip == ipl*/ ) {// authentication found (coming from map server) + /* restrictions apply */ + if( char_server_type == CST_MAINTENANCE && node->group_id < char_maintenance_min_group_id ) { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0;// rejected from server + WFIFOSET(fd,3); + break; + } idb_remove(auth_db, account_id); char_auth_ok(fd, sd); } @@ -4592,7 +4609,7 @@ int check_connect_login_server(int tid, int64 tick, int id, intptr_t data) { WFIFOW(login_fd,58) = htons(char_port); memcpy(WFIFOP(login_fd,60), server_name, 20); WFIFOW(login_fd,80) = 0; - WFIFOW(login_fd,82) = char_maintenance; + WFIFOW(login_fd,82) = char_server_type; WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] WFIFOSET(login_fd,86); @@ -4852,8 +4869,8 @@ int char_config_read(const char* cfgName) } } else if (strcmpi(w1, "char_port") == 0) { char_port = atoi(w2); - } else if (strcmpi(w1, "char_maintenance") == 0) { - char_maintenance = atoi(w2); + } else if (strcmpi(w1, "char_server_type") == 0) { + char_server_type = atoi(w2); } else if (strcmpi(w1, "char_new") == 0) { char_new = (bool)atoi(w2); } else if (strcmpi(w1, "char_new_display") == 0) { @@ -4940,6 +4957,8 @@ int char_config_read(const char* cfgName) } } else if (strcmpi(w1, "guild_exp_rate") == 0) { guild_exp_rate = atoi(w2); + } else if (strcmpi(w1, "char_maintenance_min_group_id") == 0) { + char_maintenance_min_group_id = atoi(w2); } else if (strcmpi(w1, "import") == 0) { char_config_read(w2); } else diff --git a/src/common/mmo.h b/src/common/mmo.h index 369f5c894ba..309203aa8bf 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -853,6 +853,14 @@ enum ammo_type { A_THROWWEAPON //9 }; +enum e_char_server_type { + CST_NORMAL = 0, + CST_MAINTENANCE = 1, + CST_OVER18 = 2, + CST_PAYING = 3, + CST_P2P = 4, +}; + /* packet size constant for itemlist */ #if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART #define MAX_ITEMLIST MAX_INVENTORY diff --git a/src/login/login.c b/src/login/login.c index 73e89d4ff76..3da592ebc80 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -65,6 +65,7 @@ struct auth_node { char sex; uint32 version; uint8 clienttype; + int group_id; }; static DBMap* auth_db; // int account_id -> struct auth_node* @@ -408,7 +409,7 @@ int parse_fromchar(int fd) //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip); // send ack - WFIFOHEAD(fd,25); + WFIFOHEAD(fd,29); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -418,7 +419,8 @@ int parse_fromchar(int fd) WFIFOL(fd,16) = request_id; WFIFOL(fd,20) = node->version; WFIFOB(fd,24) = node->clienttype; - WFIFOSET(fd,25); + WFIFOL(fd,25) = node->group_id; + WFIFOSET(fd,29); // each auth entry can only be used once idb_remove(auth_db, account_id); @@ -426,7 +428,7 @@ int parse_fromchar(int fd) else {// authentication not found ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip); - WFIFOHEAD(fd,25); + WFIFOHEAD(fd,29); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -436,7 +438,8 @@ int parse_fromchar(int fd) WFIFOL(fd,16) = request_id; WFIFOL(fd,20) = 0; WFIFOB(fd,24) = 0; - WFIFOSET(fd,25); + WFIFOL(fd,25) = 0; + WFIFOSET(fd,29); } } break; @@ -1206,6 +1209,7 @@ void login_auth_ok(struct login_session_data* sd) node->ip = ip; node->version = sd->version; node->clienttype = sd->clienttype; + node->group_id = sd->group_id; idb_put(auth_db, sd->account_id, node); {