summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-11-16 16:30:11 -0200
committershennetsind <ind@henn.et>2013-11-16 16:30:11 -0200
commitaee2f6317e1c927847993801b5973d7e2e27a418 (patch)
treef39d86f489a9f922857718fa4ada68563eaf2503 /src
parent45ef2298022fcc50e2609c5f9363fd56d4dd3079 (diff)
downloadhercules-aee2f6317e1c927847993801b5973d7e2e27a418.tar.gz
hercules-aee2f6317e1c927847993801b5973d7e2e27a418.tar.bz2
hercules-aee2f6317e1c927847993801b5973d7e2e27a418.tar.xz
hercules-aee2f6317e1c927847993801b5973d7e2e27a418.zip
Introducing Character Ban Support.
@charban/@charunban, can temporarily block any accounts as opposed to the usual account-wide block. Special Thanks to Haruna, Yommy! Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c215
-rw-r--r--src/char/char.h1
-rw-r--r--src/common/showmsg.h1
-rw-r--r--src/common/utils.c11
-rw-r--r--src/common/utils.h2
-rw-r--r--src/login/login.c13
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/chrif.c24
-rw-r--r--src/map/clif.c32
-rw-r--r--src/map/clif.h2
10 files changed, 232 insertions, 77 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 112bbe0ae..ce05f32f4 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1004,6 +1004,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
struct mmo_charstatus p;
int j = 0, i;
char last_map[MAP_NAME_LENGTH_EXT];
+ size_t unban_time;
stmt = SQL->StmtMalloc(sql_handle);
if( stmt == NULL ) {
@@ -1012,8 +1013,10 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
}
memset(&p, 0, sizeof(p));
- for(i = 0 ; i < MAX_CHARS; i++ )
+ for(i = 0 ; i < MAX_CHARS; i++ ) {
sd->found_char[i] = -1;
+ sd->unban_time[i] = 0;
+ }
// read char data
if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT "
@@ -1021,7 +1024,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
"`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
- "`robe`,`slotchange`"
+ "`robe`,`slotchange`,`unban_time`"
" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
|| SQL_ERROR == SQL->StmtExecute(stmt)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL)
@@ -1061,6 +1064,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_LONG, &unban_time, 0, NULL, NULL)
)
{
SqlStmt_ShowDebug(stmt);
@@ -1071,6 +1075,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->StmtNextRow(stmt); i++ ) {
p.last_point.map = mapindex_name2id(last_map);
sd->found_char[p.slot] = p.char_id;
+ sd->unban_time[p.slot] = unban_time;
j += mmo_char_tobuf(WBUFP(buf, j), &p);
}
@@ -1931,6 +1936,7 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) {
return 106+offset;
}
+
/* Made Possible by Yommy~! <3 */
void mmo_char_send099d(int fd, struct char_session_data *sd) {
WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
@@ -1938,6 +1944,34 @@ void mmo_char_send099d(int fd, struct char_session_data *sd) {
WFIFOW(fd,2) = mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4;
WFIFOSET(fd,WFIFOW(fd,2));
}
+/* Sends character ban list */
+/* Made Possible by Yommy~! <3 */
+void mmo_char_send020d(int fd, struct char_session_data *sd) {
+ int i;
+ time_t now = time(NULL);
+
+ ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now);
+
+ if( i != MAX_CHARS ) {
+ int c;
+
+ WFIFOHEAD(fd, 4 + (MAX_CHARS*24));
+
+ WFIFOW(fd, 0) = 0x20d;
+
+ for(i = 0, c = 0; i < MAX_CHARS; i++) {
+ if( sd->unban_time[i] > now ) {
+ WFIFOL(fd, 4 + (24*c)) = sd->found_char[i];
+ timestamp2string((char*)WFIFOP(fd,8 + (28*c)), 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
+ c++;
+ }
+ }
+
+ WFIFOW(fd, 2) = 4 + (24*c);
+
+ WFIFOSET(fd, WFIFOW(fd, 2));
+ }
+}
int mmo_char_send006b(int fd, struct char_session_data* sd);
//----------------------------------------
// [Ind/Hercules] notify client about charselect window data
@@ -2304,6 +2338,9 @@ int parse_fromlogin(int fd) {
#else
mmo_char_send006b(i, sd);
#endif
+ #if PACKETVER >= 20080000
+ mmo_char_send020d(i, sd);
+ #endif
#if PACKETVER >= 20110309
pincode->handle(i, sd);
#endif
@@ -3141,7 +3178,7 @@ int parse_frommap(int fd)
RFIFOSKIP(fd, 86);
break;
- case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server)
+ case 0x2b0e: // Request from map-server to change an account's or character's status (accounts will just be forwarded to login server)
if (RFIFOREST(fd) < 44)
return 0;
{
@@ -3150,7 +3187,7 @@ int parse_frommap(int fd)
int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
const char* name = (char*)RFIFOP(fd,6); // name of the target character
- int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
+ int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5 changesex, 6 charban, 7 charunban
short year = RFIFOW(fd,32);
short month = RFIFOW(fd,34);
short day = RFIFOW(fd,36);
@@ -3160,25 +3197,24 @@ int parse_frommap(int fd)
RFIFOSKIP(fd,44);
SQL->EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
+
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
Sql_ShowDebug(sql_handle);
- else
- if( SQL->NumRows(sql_handle) == 0 )
- {
+ else if( SQL->NumRows(sql_handle) == 0 ) {
result = 1; // 1-player not found
- }
- else
- if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
+ } else if( SQL_SUCCESS != SQL->NextRow(sql_handle) ) {
Sql_ShowDebug(sql_handle);
- //FIXME: set proper result value?
- else
- {
+ result = 1; // 1-player not found
+ } else {
char name[NAME_LENGTH];
- int account_id;
+ int account_id, char_id;
char* data;
+ time_t unban_time;
SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
+ SQL->GetData(sql_handle, 2, &data, NULL); char_id = atoi(data);
+ SQL->GetData(sql_handle, 3, &data, NULL); unban_time = atol(data);
if( login_fd <= 0 )
result = 3; // 3-login-server offline
@@ -3186,53 +3222,111 @@ int parse_frommap(int fd)
// else
// if( acc != -1 && isGM(acc) < isGM(account_id) )
// result = 2; // 2-gm level too low
- else
- switch( type ) {
- case 1: // block
- WFIFOHEAD(login_fd,10);
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = account_id;
- WFIFOL(login_fd,6) = 5; // new account status
- WFIFOSET(login_fd,10);
- break;
- case 2: // ban
- WFIFOHEAD(login_fd,18);
- WFIFOW(login_fd, 0) = 0x2725;
- WFIFOL(login_fd, 2) = account_id;
- WFIFOW(login_fd, 6) = year;
- WFIFOW(login_fd, 8) = month;
- WFIFOW(login_fd,10) = day;
- WFIFOW(login_fd,12) = hour;
- WFIFOW(login_fd,14) = minute;
- WFIFOW(login_fd,16) = second;
- WFIFOSET(login_fd,18);
- break;
- case 3: // unblock
- WFIFOHEAD(login_fd,10);
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = account_id;
- WFIFOL(login_fd,6) = 0; // new account status
- WFIFOSET(login_fd,10);
- break;
- case 4: // unban
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x272a;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- break;
- case 5: // changesex
- WFIFOHEAD(login_fd,6);
- WFIFOW(login_fd,0) = 0x2727;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- break;
+ else {
+ switch( type ) {
+ case 1: // block
+ WFIFOHEAD(login_fd,10);
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOL(login_fd,6) = 5; // new account status
+ WFIFOSET(login_fd,10);
+ break;
+ case 2: // ban
+ WFIFOHEAD(login_fd,18);
+ WFIFOW(login_fd, 0) = 0x2725;
+ WFIFOL(login_fd, 2) = account_id;
+ WFIFOW(login_fd, 6) = year;
+ WFIFOW(login_fd, 8) = month;
+ WFIFOW(login_fd,10) = day;
+ WFIFOW(login_fd,12) = hour;
+ WFIFOW(login_fd,14) = minute;
+ WFIFOW(login_fd,16) = second;
+ WFIFOSET(login_fd,18);
+ break;
+ case 3: // unblock
+ WFIFOHEAD(login_fd,10);
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOL(login_fd,6) = 0; // new account status
+ WFIFOSET(login_fd,10);
+ break;
+ case 4: // unban
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x272a;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ break;
+ case 5: // changesex
+ WFIFOHEAD(login_fd,6);
+ WFIFOW(login_fd,0) = 0x2727;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+ break;
+ case 6: //char ban
+ /* handled by char server, so no redirection */
+ {
+ time_t timestamp;
+ struct tm *tmtime;
+ SqlStmt* stmt = SQL->StmtMalloc(sql_handle);
+
+ if (unban_time == 0 || unban_time < time(NULL))
+ timestamp = time(NULL); // new ban
+ else
+ timestamp = unban_time; // add to existing ban
+
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + year;
+ tmtime->tm_mon = tmtime->tm_mon + month;
+ tmtime->tm_mday = tmtime->tm_mday + day;
+ tmtime->tm_hour = tmtime->tm_hour + hour;
+ tmtime->tm_min = tmtime->tm_min + minute;
+ tmtime->tm_sec = tmtime->tm_sec + second;
+ timestamp = mktime(tmtime);
+
+ if( SQL_SUCCESS != SQL->StmtPrepare(stmt,
+ "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
+ char_db)
+ || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_LONG, (void*)&timestamp, sizeof(timestamp))
+ || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_INT, (void*)&char_id, sizeof(char_id))
+ || SQL_SUCCESS != SQL->StmtExecute(stmt)
+
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ }
+
+ SQL->StmtFree(stmt);
+
+ // condition applies; send to all map-servers to disconnect the player
+ if( timestamp > time(NULL) ) {
+ unsigned char buf[11];
+
+ WBUFW(buf,0) = 0x2b14;
+ WBUFL(buf,2) = account_id;
+ WBUFB(buf,6) = 2;
+ WBUFL(buf,7) = (unsigned int)timestamp;
+ mapif_sendall(buf, 11);
+
+ // disconnect player if online on char-server
+ disconnect_player(account_id);
+ }
+ }
+ break;
+ case 7: //char unban
+ /* handled by char server, so no redirection */
+ if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `unban_time` = '0' WHERE `char_id` = '%d' LIMIT 1", char_db, char_id) ) {
+ Sql_ShowDebug(sql_handle);
+ result = 1;
+ }
+ break;
+
+ }
}
}
SQL->FreeResult(sql_handle);
// send answer if a player ask, not if the server ask
- if( acc != -1 && type != 5) { // Don't send answer for changesex
+ if( acc != -1 && type != 5 ) { // Don't send answer for changesex
WFIFOHEAD(fd,34);
WFIFOW(fd, 0) = 0x2b0f;
WFIFOL(fd, 2) = acc;
@@ -3984,6 +4078,15 @@ int parse_char(int fd)
char_id = atoi(data);
SQL->FreeResult(sql_handle);
+ /* client doesn't let it get to this point if you're banned, so its a forged packet */
+ if( sd->found_char[slot] == char_id && sd->unban_time[slot] > time(NULL) ) {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOB(fd,2) = 0; // rejected from server
+ WFIFOSET(fd,3);
+ break;
+ }
+
/* set char as online prior to loading its data so 3rd party applications will realise the sql data is not reliable */
set_char_online(-2,char_id,sd->account_id);
if( !mmo_char_fromsql(char_id, &char_dat, true) ) { /* failed? set it back offline */
diff --git a/src/char/char.h b/src/char/char.h
index a3bbdd904..c7a387645 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -20,6 +20,7 @@ struct char_session_data {
bool auth; // whether the session is authed or not
int account_id, login_id1, login_id2, sex;
int found_char[MAX_CHARS]; // ids of chars on this account
+ time_t unban_time[MAX_CHARS]; // char unban time array
char email[40]; // e-mail (default: a@a.com) by [Yor]
time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
int group_id; // permission
diff --git a/src/common/showmsg.h b/src/common/showmsg.h
index 59a0d9538..43d38973f 100644
--- a/src/common/showmsg.h
+++ b/src/common/showmsg.h
@@ -99,5 +99,6 @@ extern void ClearScreen(void);
extern void ShowFatalError(const char *, ...);
extern void ShowConfigWarning(config_setting_t *config, const char *string, ...);
#endif
+extern int _vShowMessage(enum msg_type flag, const char *string, va_list ap);
#endif /* _SHOWMSG_H_ */
diff --git a/src/common/utils.c b/src/common/utils.c
index 9e3dbac47..9a7d4971b 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -287,6 +287,17 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B)
return (unsigned int)floor(result);
}
+//-----------------------------------------------------
+// custom timestamp formatting (from eApp)
+//-----------------------------------------------------
+const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
+{
+ size_t len = strftime(str, size, format, localtime(&timestamp));
+ memset(str + len, '\0', size - len);
+ return str;
+}
+
+
/* [Ind/Hercules] Caching */
bool HCache_check(const char *file) {
struct stat bufa, bufb;
diff --git a/src/common/utils.h b/src/common/utils.h
index 32087d78f..3e1463d6b 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -25,6 +25,8 @@ bool exists(const char* filename);
/// calculates the value of A / B, in percent (rounded down)
unsigned int get_percentage(const unsigned int A, const unsigned int B);
+const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format);
+
//////////////////////////////////////////////////////////////////////////
// byte word dword access [Shinomori]
//////////////////////////////////////////////////////////////////////////
diff --git a/src/login/login.c b/src/login/login.c
index 3da592ebc..75247845d 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -11,6 +11,7 @@
#include "../common/socket.h"
#include "../common/strlib.h"
#include "../common/timer.h"
+#include "../common/utils.h"
#include "../common/HPM.h"
#include "account.h"
#include "ipban.h"
@@ -271,18 +272,6 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const
}
}
-
-//-----------------------------------------------------
-// custom timestamp formatting (from eApp)
-//-----------------------------------------------------
-const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
-{
- size_t len = strftime(str, size, format, localtime(&timestamp));
- memset(str + len, '\0', size - len);
- return str;
-}
-
-
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
//--------------------------------------------
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 902d179db..a2bea32a8 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2798,7 +2798,7 @@ ACMD(char_ban)
return false;
}
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charban") ? 6 : 2, year, month, day, hour, minute, second); // type: 2 - ban; 6 - charban
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -2838,7 +2838,7 @@ ACMD(char_unban)
}
// send answer to login server via char-server
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charunban") ? 7 : 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban account; type 7 - unban character
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -3138,7 +3138,7 @@ ACMD(spiritball)
if( !message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs )
{
char msg[CHAT_SIZE_MAX];
- safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter a party name (usage: @party <party_name>).
+ safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter an amount (usage: @spiritball <number: 0-%d>).
clif->message(fd, msg);
return false;
}
@@ -9448,7 +9448,9 @@ void atcommand_basecommands(void) {
ACMD_DEF2("allstats", stat_all),
ACMD_DEF2("block", char_block),
ACMD_DEF2("ban", char_ban),
+ ACMD_DEF2("charban", char_ban),/* char-specific ban time */
ACMD_DEF2("unblock", char_unblock),
+ ACMD_DEF2("charunban", char_unban),/* char-specific ban time */
ACMD_DEF2("unban", char_unban),
ACMD_DEF2("mount", mount_peco),
ACMD_DEF(guildspy),
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 87ec71ec5..56572d492 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -752,7 +752,7 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) {
* S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
* Send an account modification request to the login server (via char server).
* type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5)
+ * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban
*------------------------------------------*/
int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) {
@@ -764,7 +764,7 @@ int chrif_char_ask_name(int acc, const char* character_name, unsigned short oper
safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH);
WFIFOW(chrif->fd,30) = operation_type;
- if ( operation_type == 2 ) {
+ if ( operation_type == 2 || operation_type == 6 ) {
WFIFOW(chrif->fd,32) = year;
WFIFOW(chrif->fd,34) = month;
WFIFOW(chrif->fd,36) = day;
@@ -800,7 +800,7 @@ int chrif_changesex(struct map_session_data *sd) {
* R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
* Processing a reply to chrif->char_ask_name() (request to modify an account).
* type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex
+ * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban
* type of answer:
* 0: login-server request done
* 1: player not found
@@ -811,6 +811,7 @@ void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
struct map_session_data* sd;
char action[25];
char output[256];
+ bool charsrv = ( type == 6 || type == 7 ) ? true : false;
sd = map->id2sd(acc);
@@ -819,13 +820,17 @@ void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
return;
}
+ /* re-use previous msg_txt */
+ if( type == 6 ) type = 2;
+ if( type == 7 ) type = 4;
+
if( type > 0 && type <= 5 )
snprintf(action,25,"%s",msg_txt(427+type)); //block|ban|unblock|unban|change the sex of
else
snprintf(action,25,"???");
switch( answer ) {
- case 0 : sprintf(output, msg_txt(424), action, NAME_LENGTH, player_name); break;
+ case 0 : sprintf(output, msg_txt(charsrv?434:424), action, NAME_LENGTH, player_name); break;
case 1 : sprintf(output, msg_txt(425), NAME_LENGTH, player_name); break;
case 2 : sprintf(output, msg_txt(426), action, NAME_LENGTH, player_name); break;
case 3 : sprintf(output, msg_txt(427), action, NAME_LENGTH, player_name); break;
@@ -980,7 +985,7 @@ int chrif_accountban(int fd) {
}
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban
+ if (RFIFOB(fd,6) == 0) { // 0: change of statut
int ret_status = RFIFOL(fd,7); // status or final date of a banishment
if(0<ret_status && ret_status<=9)
clif->message(sd->fd, msg_txt(411+ret_status));
@@ -988,13 +993,20 @@ int chrif_accountban(int fd) {
clif->message(sd->fd, msg_txt(421));
else
clif->message(sd->fd, msg_txt(420)); //"Your account has not more authorised."
- } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban
+ } else if (RFIFOB(fd,6) == 1) { // 1: ban
time_t timestamp;
char tmpstr[2048];
timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until "
strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
clif->message(sd->fd, tmpstr);
+ } else if (RFIFOB(fd,6) == 2) { // 2: change of status for character
+ time_t timestamp;
+ char tmpstr[2048];
+ timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
+ strcpy(tmpstr, msg_txt(433)); //"This character has been banned until "
+ strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
+ clif->message(sd->fd, tmpstr);
}
set_eof(sd->fd); // forced to disconnect for the change
diff --git a/src/map/clif.c b/src/map/clif.c
index d84a0dea8..6740c7a74 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -5634,7 +5634,38 @@ void clif_displaymessage2(const int fd, const char* mes) {
aFree(message);
}
}
+/* oh noo! another version of 0x8e! */
+void clif_displaymessage_sprintf(const int fd, const char* mes, ...) {
+ va_list ap;
+ if( fd == -2 ) {
+ ShowInfo("HCP: ");
+ va_start(ap,mes);
+ _vShowMessage(MSG_NONE,mes,ap);
+ va_end(ap);
+ ShowMessage("\n");
+ } else if ( fd > 0 ) {
+ int len = 1;
+ char *ptr;
+
+ WFIFOHEAD(fd, 5 + 255);/* ensure the maximum */
+
+ /* process */
+ va_start(ap,mes);
+ len += vsnprintf((char *)WFIFOP(fd,4), 255, mes, ap);
+ va_end(ap);
+
+ /* adjusting */
+ ptr = (char *)WFIFOP(fd,4);
+ ptr[len - 1] = '\0';
+
+ /* */
+ WFIFOW(fd,0) = 0x8e;
+ WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate
+
+ WFIFOSET(fd, 5 + len);
+ }
+}
/// Send broadcast message in yellow or blue without font formatting (ZC_BROADCAST).
/// 009a <packet len>.W <message>.?B
void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target)
@@ -18407,6 +18438,7 @@ void clif_defaults(void) {
clif->msgtable_num = clif_msgtable_num;
clif->message = clif_displaymessage;
clif->messageln = clif_displaymessage2;
+ clif->messages = clif_displaymessage_sprintf;
clif->colormes = clif_colormes;
clif->process_message = clif_process_message;
clif->wisexin = clif_wisexin;
diff --git a/src/map/clif.h b/src/map/clif.h
index e50af7432..043f7dd3a 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -787,6 +787,8 @@ struct clif_interface {
void (*msgtable_num) (int fd, int line, int num);
void (*message) (const int fd, const char* mes);
void (*messageln) (const int fd, const char* mes);
+ /* message+s(printf) */
+ void (*messages) (const int fd, const char* mes, ...);
int (*colormes) (int fd, enum clif_colors color, const char* msg);
bool (*process_message) (struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_);
void (*wisexin) (struct map_session_data *sd,int type,int flag);