summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/login_sql/char_int.c982
-rw-r--r--src/login_sql/char_int.h4
-rw-r--r--src/login_sql/login_int.c740
-rw-r--r--src/login_sql/login_int.h2
-rw-r--r--src/map/charcommand.c1406
-rw-r--r--src/map/charcommand.h100
-rw-r--r--src/webserver/Changelog.txt4
-rw-r--r--src/webserver/Makefile64
-rw-r--r--src/webserver/Makefile.win70
-rw-r--r--src/webserver/WEBSER~1.layout48
-rw-r--r--src/webserver/Webserver.dev194
-rw-r--r--src/webserver/Webserver.layout76
-rw-r--r--src/webserver/conf/webserver-athena.conf72
-rw-r--r--src/webserver/main.c288
-rw-r--r--src/webserver/webserver.c272
-rw-r--r--src/webserver/webserver.h42
16 files changed, 2182 insertions, 2182 deletions
diff --git a/src/login_sql/char_int.c b/src/login_sql/char_int.c
index 09daefe2b..be0de499c 100644
--- a/src/login_sql/char_int.c
+++ b/src/login_sql/char_int.c
@@ -1,491 +1,491 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "login.h"
-
-//--------------------------------
-// Send to char
-//--------------------------------
-int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
- int i, c;
- int fd;
-
- c = 0;
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
- if ((fd = server_fd[i]) > 0 && fd != sfd) {
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- c++;
- }
- }
-
- return c;
-}
-
-//--------------------------------
-// Char-server anti-freeze system
-//--------------------------------
-int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
- int i;
-
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
- if (server_fd[i] >= 0) {// if char-server is online
-// printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
- if (server_freezeflag[i]-- < 1) {// Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
- session[server_fd[i]]->eof = 1;
- }
- }
- }
-
- return 0;
-}
-
-//-------------------------------------------
-// Request for account reg from char-server [Edit: Wizputer]
-//-------------------------------------------
-void send_account_reg(int fd) {
- int account_id = RFIFOL(fd,2);
- int i;
-
- for(i=0;i<AUTH_FIFO_SIZE;i++){
- if (auth_fifo[i].account_id == account_id &&
- auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
-#if CMP_AUTHFIFO_LOGIN2 != 0
- auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
-#endif
- auth_fifo[i].sex == RFIFOB(fd,14) &&
-#if CMP_AUTHFIFO_IP != 0
- auth_fifo[i].ip == RFIFOL(fd,15) &&
-#endif
- !auth_fifo[i].delflag) {
- auth_fifo[i].delflag = 1;
- #ifdef DEBUG
- printf("Client: [%d] Auth Number: [%d]\n",fd, i);
- #endif
- break;
- }
- }
-
- if (i != AUTH_FIFO_SIZE) { // send account_reg
- int p;
- time_t connect_until_time = 0;
- char email[40] = "";
-
- sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
- sql_query(tmpsql,"send_account_reg");
-
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {
- connect_until_time = atol(sql_row[1]);
- strcpy(email, sql_row[0]);
- }
- }
- mysql_free_result(sql_res);
-
- if (account_id > 0) {
- sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
- sql_query(tmpsql,"send_account_reg");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- WFIFOW(fd,0) = 0x2729;
- WFIFOL(fd,4) = account_id;
- for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
- memcpy(WFIFOP(fd,p), sql_row[0], 32);
- WFIFOL(fd,p+32) = atoi(sql_row[1]);
- }
- WFIFOW(fd,2) = p;
- WFIFOSET(fd,p);
- #ifdef DEBUG
- printf("account_reg2 send : login->char (auth fifo)\n");
- #endif
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 0;
- memcpy(WFIFOP(fd, 7), email, 40);
- WFIFOL(fd,47) = (unsigned long) connect_until_time;
- WFIFOSET(fd,51);
- }
- mysql_free_result(sql_res);
- }
- } else {
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 1;
- WFIFOSET(fd,51);
- }
- RFIFOSKIP(fd,19);
-}
-
-//----------------------------------------------------------
-// Number of users in the world (connected char-server(s)) [Edit: Wizputer]
-//----------------------------------------------------------
-void number_world_users(int fd, int id) {
- #ifdef DEBUG
- if (server[id].users != RFIFOL(fd,2))
- printf("set number users %s : %d\n", server[id].name, RFIFOL(fd,2));
- #endif
-
- server[id].users = RFIFOL(fd,2);
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
-
- sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
- sql_query(tmpsql,"number_world_users");
-
- RFIFOSKIP(fd,6);
-}
-
-//-----------------------------------------
-// Email and Time request from char-server [Edit: Wizputer]
-//-----------------------------------------
-void email_time_request(int fd, int id) {
- int account_id=RFIFOL(fd,2);
- time_t connect_until_time = 0;
- char email[40] = "";
-
- sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
- sql_query(tmpsql,"email_time_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {
- connect_until_time = atol(sql_row[1]);
- strcpy(email, sql_row[0]);
- }
- }
- mysql_free_result(sql_res);
-
- #ifdef DEBUG
- printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, account_id);
- #endif
-
- WFIFOW(fd,0) = 0x2717;
- WFIFOL(fd,2) = account_id;
- memcpy(WFIFOP(fd, 6), email, 40);
- WFIFOL(fd,46) = (unsigned long) connect_until_time;
- WFIFOSET(fd,50);
-
- RFIFOSKIP(fd,6);
-}
-
-//--------------------------------
-// Request to change email [Edit: Wizputer]
-//--------------------------------
-void change_account_email(int fd, int id, char ip[16]) {
- int acc = RFIFOL(fd,2);
- char actual_email[40], new_email[40];
-
- memcpy(actual_email, RFIFOP(fd,6), 40);
- memcpy(new_email, RFIFOP(fd,46), 40);
-
- if (e_mail_check(actual_email) == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else if (e_mail_check(new_email) == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else if (strcmpi(new_email, "athena@athena.com") == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else {
- sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
- sql_query(tmpsql,"change_account_email");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) { //row fetching
- if (strcmpi(sql_row[1], actual_email) == 0) {
- sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
- sql_query(tmpsql,"change_account_email");
-
- #ifdef DEBUG
- printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
- server[id].name, acc, sql_row[0], actual_email, ip);
- #endif
- }
- }
- }
-
- }
-
- RFIFOSKIP(fd, 86);
-}
-
-//-----------------------------------------------
-// State change request from map server (By Yor) [Edit: Wizputer]
-//-----------------------------------------------
-void status_change_request(int fd) {
- int acc = RFIFOL(fd,2), status = RFIFOL(fd,6);
-
- sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
- sql_query(tmpsql,"status_change_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) { // row fetching
- if (atoi(sql_row[0]) != status && status != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
- WBUFL(buf,7) = status; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- }
-
- sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, status,login_db_account_id,acc);
- sql_query(tmpsql,"status_change_request");
- }
-
- RFIFOSKIP(fd,10);
-}
-//--------------------------------------
-// Ban request from map-server (By Yor) [Edit: Wizputer]
-//--------------------------------------
-void ban_request(int fd) {
- int acc=RFIFOL(fd,2);
- struct tm *tmtime;
- time_t timestamp, tmptime;
-
- sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
- sql_query(tmpsql,"ban_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- tmptime = atol(sql_row[0]);
-
- if (tmptime == 0 || tmptime < time(NULL))
- timestamp = time(NULL);
- else
- timestamp = tmptime;
-
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
-
- timestamp = mktime(tmtime);
-
- if (timestamp != -1) {
- if (timestamp <= time(NULL))
- timestamp = 0;
- if (tmptime != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- #ifdef DEBUG
- printf("Account: [%d] Banned until: [%ld]\n", acc, timestamp);
- #endif
-
- sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
- sql_query(tmpsql,"ban_request");
- }
- }
- }
-
- RFIFOSKIP(fd,18);
-}
-
-//-----------------------------
-// Change sex [Edit: Wizputer]
-//-----------------------------
-void change_sex(int fd) {
- int sex,acc=RFIFOL(fd,4);
- unsigned char buf[16];
-
- sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
- sql_query(tmpsql,"change_sex");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- if (strcmpi(sql_row[0], "M") == 0)
- sex = 1;
- else
- sex = 0;
-
- sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
- sql_query(tmpsql,"change_sex");
-
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
- charif_sendallwos(-1, buf, 7);
- }
-
- RFIFOSKIP(fd,6);
-}
-
-//-------------------------------
-// Save Account Reg [Edit: Wizputer]
-//-------------------------------
-void save_account_reg(int fd){
- int p,j,value,acc=RFIFOL(fd,4);
- char str[32];
- char temp_str[32];
-
- if (acc>0){
- unsigned char buf[RFIFOW(fd,2)+1];
- for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
- memcpy(str,RFIFOP(fd,p),32);
- value=RFIFOL(fd,p+32);
-
- sprintf(tmpsql,"REPLACE INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
- sql_query(tmpsql,"save_account_reg");
- }
-
- // Send to char
- memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
- WBUFW(buf,0)=0x2729;
- charif_sendallwos(fd,buf,WBUFW(buf,2));
- }
-
- RFIFOSKIP(fd,RFIFOW(fd,2));
-
- #ifdef DEBUG
- printf("login: save account_reg (from char)\n");
- #endif
-}
-
-//------------------------------------------------
-// Recieve unban request from map-server (by Yor) [Edit: Wizputer]
-//------------------------------------------------
-void unban_request(int fd) {
- int acc = RFIFOL(fd,2);
-
- sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d' AND `state`='6'", login_db,login_db_account_id,acc);
- sql_query(tmpsql,"unban_request");
-
- RFIFOSKIP(fd,6);
-}
-
-//-----------------------------------------------------
-// char-server packet parse [Edit: Wizputer]
-//-----------------------------------------------------
-int parse_fromchar(int fd){
- int id;
-
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- char ip[16];
-
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-
- for(id = 0; id < MAX_SERVERS && id < servers_connected; id++)
- if (server_fd[id] == fd)
- break;
-
- if (id == MAX_SERVERS)
- session[fd]->eof = 1;
-
- if(session[fd]->eof) {
- if (id < MAX_SERVERS) {
- printf("Char-server '%s' has disconnected.\n", server[id].name);
- server_fd[id] = -1;
- memset(&server[id], 0, sizeof(struct mmo_char_server));
- servers_connected--;
- // server delete
- sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
- sql_query(tmpsql,"parse_fromchar");
- }
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- while(RFIFOREST(fd) >= 2) {
- #ifdef DEBUG_PACKETS
- printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
- #endif
-
- switch (RFIFOW(fd,0)) {
- case 0x2712:
- if (RFIFOREST(fd) < 19)
- return 0;
- send_account_reg(fd);
- break;
-
- case 0x2714:
- if (RFIFOREST(fd) < 6)
- return 0;
- number_world_users(fd,id);
- break;
-
- case 0x2716:
- if (RFIFOREST(fd) < 6)
- return 0;
- email_time_request(fd, id);
- break;
-
- case 0x2722:
- if (RFIFOREST(fd) < 86)
- return 0;
- change_account_email(fd, id, ip);
- break;
-
- case 0x2724:
- if (RFIFOREST(fd) < 10)
- return 0;
- status_change_request(fd);
- break;
-
- case 0x2725:
- if (RFIFOREST(fd) < 18)
- return 0;
- ban_request(fd);
- break;
-
- case 0x2727:
- if (RFIFOREST(fd) < 6)
- return 0;
- change_sex(fd);
- break;
-
- case 0x2728:
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- save_account_reg(fd);
- break;
-
- case 0x272a:
- if (RFIFOREST(fd) < 6)
- return 0;
- unban_request(fd);
- return 0;
-
- case 0x272b: // Set account_id to online [Wizputer]
- if (RFIFOREST(fd) < 6)
- return 0;
- add_online_user(RFIFOL(fd,2));
- RFIFOSKIP(fd,6);
- break;
-
- case 0x272c: // Set account_id to offline [Wizputer]
- if (RFIFOREST(fd) < 6)
- return 0;
- remove_online_user(RFIFOL(fd,2));
- RFIFOSKIP(fd,6);
- break;
-
- default:
- #ifdef DEBUG
- printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
- #endif
- session[fd]->eof = 1;
- }
- }
-
- return 0;
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "login.h"
+
+//--------------------------------
+// Send to char
+//--------------------------------
+int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
+ int i, c;
+ int fd;
+
+ c = 0;
+ for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
+ if ((fd = server_fd[i]) > 0 && fd != sfd) {
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ c++;
+ }
+ }
+
+ return c;
+}
+
+//--------------------------------
+// Char-server anti-freeze system
+//--------------------------------
+int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
+ int i;
+
+ for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
+ if (server_fd[i] >= 0) {// if char-server is online
+// printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
+ if (server_freezeflag[i]-- < 1) {// Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
+ session[server_fd[i]]->eof = 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+//-------------------------------------------
+// Request for account reg from char-server [Edit: Wizputer]
+//-------------------------------------------
+void send_account_reg(int fd) {
+ int account_id = RFIFOL(fd,2);
+ int i;
+
+ for(i=0;i<AUTH_FIFO_SIZE;i++){
+ if (auth_fifo[i].account_id == account_id &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
+#if CMP_AUTHFIFO_LOGIN2 != 0
+ auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
+#endif
+ auth_fifo[i].sex == RFIFOB(fd,14) &&
+#if CMP_AUTHFIFO_IP != 0
+ auth_fifo[i].ip == RFIFOL(fd,15) &&
+#endif
+ !auth_fifo[i].delflag) {
+ auth_fifo[i].delflag = 1;
+ #ifdef DEBUG
+ printf("Client: [%d] Auth Number: [%d]\n",fd, i);
+ #endif
+ break;
+ }
+ }
+
+ if (i != AUTH_FIFO_SIZE) { // send account_reg
+ int p;
+ time_t connect_until_time = 0;
+ char email[40] = "";
+
+ sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
+ sql_query(tmpsql,"send_account_reg");
+
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if((sql_row = mysql_fetch_row(sql_res))) {
+ connect_until_time = atol(sql_row[1]);
+ strcpy(email, sql_row[0]);
+ }
+ }
+ mysql_free_result(sql_res);
+
+ if (account_id > 0) {
+ sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
+ sql_query(tmpsql,"send_account_reg");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ WFIFOW(fd,0) = 0x2729;
+ WFIFOL(fd,4) = account_id;
+ for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
+ memcpy(WFIFOP(fd,p), sql_row[0], 32);
+ WFIFOL(fd,p+32) = atoi(sql_row[1]);
+ }
+ WFIFOW(fd,2) = p;
+ WFIFOSET(fd,p);
+ #ifdef DEBUG
+ printf("account_reg2 send : login->char (auth fifo)\n");
+ #endif
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 0;
+ memcpy(WFIFOP(fd, 7), email, 40);
+ WFIFOL(fd,47) = (unsigned long) connect_until_time;
+ WFIFOSET(fd,51);
+ }
+ mysql_free_result(sql_res);
+ }
+ } else {
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 1;
+ WFIFOSET(fd,51);
+ }
+ RFIFOSKIP(fd,19);
+}
+
+//----------------------------------------------------------
+// Number of users in the world (connected char-server(s)) [Edit: Wizputer]
+//----------------------------------------------------------
+void number_world_users(int fd, int id) {
+ #ifdef DEBUG
+ if (server[id].users != RFIFOL(fd,2))
+ printf("set number users %s : %d\n", server[id].name, RFIFOL(fd,2));
+ #endif
+
+ server[id].users = RFIFOL(fd,2);
+ if(anti_freeze_enable)
+ server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
+
+ sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
+ sql_query(tmpsql,"number_world_users");
+
+ RFIFOSKIP(fd,6);
+}
+
+//-----------------------------------------
+// Email and Time request from char-server [Edit: Wizputer]
+//-----------------------------------------
+void email_time_request(int fd, int id) {
+ int account_id=RFIFOL(fd,2);
+ time_t connect_until_time = 0;
+ char email[40] = "";
+
+ sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
+ sql_query(tmpsql,"email_time_request");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if((sql_row = mysql_fetch_row(sql_res))) {
+ connect_until_time = atol(sql_row[1]);
+ strcpy(email, sql_row[0]);
+ }
+ }
+ mysql_free_result(sql_res);
+
+ #ifdef DEBUG
+ printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, account_id);
+ #endif
+
+ WFIFOW(fd,0) = 0x2717;
+ WFIFOL(fd,2) = account_id;
+ memcpy(WFIFOP(fd, 6), email, 40);
+ WFIFOL(fd,46) = (unsigned long) connect_until_time;
+ WFIFOSET(fd,50);
+
+ RFIFOSKIP(fd,6);
+}
+
+//--------------------------------
+// Request to change email [Edit: Wizputer]
+//--------------------------------
+void change_account_email(int fd, int id, char ip[16]) {
+ int acc = RFIFOL(fd,2);
+ char actual_email[40], new_email[40];
+
+ memcpy(actual_email, RFIFOP(fd,6), 40);
+ memcpy(new_email, RFIFOP(fd,46), 40);
+
+ if (e_mail_check(actual_email) == 0) {
+ #ifdef DEBUG
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ #endif
+ } else if (e_mail_check(new_email) == 0) {
+ #ifdef DEBUG
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ #endif
+ } else if (strcmpi(new_email, "athena@athena.com") == 0) {
+ #ifdef DEBUG
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ #endif
+ } else {
+ sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
+ sql_query(tmpsql,"change_account_email");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if((sql_row = mysql_fetch_row(sql_res))) { //row fetching
+ if (strcmpi(sql_row[1], actual_email) == 0) {
+ sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
+ sql_query(tmpsql,"change_account_email");
+
+ #ifdef DEBUG
+ printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
+ server[id].name, acc, sql_row[0], actual_email, ip);
+ #endif
+ }
+ }
+ }
+
+ }
+
+ RFIFOSKIP(fd, 86);
+}
+
+//-----------------------------------------------
+// State change request from map server (By Yor) [Edit: Wizputer]
+//-----------------------------------------------
+void status_change_request(int fd) {
+ int acc = RFIFOL(fd,2), status = RFIFOL(fd,6);
+
+ sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
+ sql_query(tmpsql,"status_change_request");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if((sql_row = mysql_fetch_row(sql_res))) { // row fetching
+ if (atoi(sql_row[0]) != status && status != 0) {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
+ WBUFL(buf,7) = status; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ }
+
+ sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, status,login_db_account_id,acc);
+ sql_query(tmpsql,"status_change_request");
+ }
+
+ RFIFOSKIP(fd,10);
+}
+//--------------------------------------
+// Ban request from map-server (By Yor) [Edit: Wizputer]
+//--------------------------------------
+void ban_request(int fd) {
+ int acc=RFIFOL(fd,2);
+ struct tm *tmtime;
+ time_t timestamp, tmptime;
+
+ sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
+ sql_query(tmpsql,"ban_request");
+
+ if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ tmptime = atol(sql_row[0]);
+
+ if (tmptime == 0 || tmptime < time(NULL))
+ timestamp = time(NULL);
+ else
+ timestamp = tmptime;
+
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
+ tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
+ tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
+ tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
+ tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
+ tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
+
+ timestamp = mktime(tmtime);
+
+ if (timestamp != -1) {
+ if (timestamp <= time(NULL))
+ timestamp = 0;
+ if (tmptime != timestamp) {
+ if (timestamp != 0) {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
+ WBUFL(buf,7) = timestamp; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ #ifdef DEBUG
+ printf("Account: [%d] Banned until: [%ld]\n", acc, timestamp);
+ #endif
+
+ sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
+ sql_query(tmpsql,"ban_request");
+ }
+ }
+ }
+
+ RFIFOSKIP(fd,18);
+}
+
+//-----------------------------
+// Change sex [Edit: Wizputer]
+//-----------------------------
+void change_sex(int fd) {
+ int sex,acc=RFIFOL(fd,4);
+ unsigned char buf[16];
+
+ sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
+ sql_query(tmpsql,"change_sex");
+
+ if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ if (strcmpi(sql_row[0], "M") == 0)
+ sex = 1;
+ else
+ sex = 0;
+
+ sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
+ sql_query(tmpsql,"change_sex");
+
+ WBUFW(buf,0) = 0x2723;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = sex;
+ charif_sendallwos(-1, buf, 7);
+ }
+
+ RFIFOSKIP(fd,6);
+}
+
+//-------------------------------
+// Save Account Reg [Edit: Wizputer]
+//-------------------------------
+void save_account_reg(int fd){
+ int p,j,value,acc=RFIFOL(fd,4);
+ char str[32];
+ char temp_str[32];
+
+ if (acc>0){
+ unsigned char buf[RFIFOW(fd,2)+1];
+ for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
+ memcpy(str,RFIFOP(fd,p),32);
+ value=RFIFOL(fd,p+32);
+
+ sprintf(tmpsql,"REPLACE INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
+ sql_query(tmpsql,"save_account_reg");
+ }
+
+ // Send to char
+ memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
+ WBUFW(buf,0)=0x2729;
+ charif_sendallwos(fd,buf,WBUFW(buf,2));
+ }
+
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+
+ #ifdef DEBUG
+ printf("login: save account_reg (from char)\n");
+ #endif
+}
+
+//------------------------------------------------
+// Recieve unban request from map-server (by Yor) [Edit: Wizputer]
+//------------------------------------------------
+void unban_request(int fd) {
+ int acc = RFIFOL(fd,2);
+
+ sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d' AND `state`='6'", login_db,login_db_account_id,acc);
+ sql_query(tmpsql,"unban_request");
+
+ RFIFOSKIP(fd,6);
+}
+
+//-----------------------------------------------------
+// char-server packet parse [Edit: Wizputer]
+//-----------------------------------------------------
+int parse_fromchar(int fd){
+ int id;
+
+ unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ char ip[16];
+
+ sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+
+ for(id = 0; id < MAX_SERVERS && id < servers_connected; id++)
+ if (server_fd[id] == fd)
+ break;
+
+ if (id == MAX_SERVERS)
+ session[fd]->eof = 1;
+
+ if(session[fd]->eof) {
+ if (id < MAX_SERVERS) {
+ printf("Char-server '%s' has disconnected.\n", server[id].name);
+ server_fd[id] = -1;
+ memset(&server[id], 0, sizeof(struct mmo_char_server));
+ servers_connected--;
+ // server delete
+ sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
+ sql_query(tmpsql,"parse_fromchar");
+ }
+ close(fd);
+ delete_session(fd);
+ return 0;
+ }
+
+ while(RFIFOREST(fd) >= 2) {
+ #ifdef DEBUG_PACKETS
+ printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+ #endif
+
+ switch (RFIFOW(fd,0)) {
+ case 0x2712:
+ if (RFIFOREST(fd) < 19)
+ return 0;
+ send_account_reg(fd);
+ break;
+
+ case 0x2714:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ number_world_users(fd,id);
+ break;
+
+ case 0x2716:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ email_time_request(fd, id);
+ break;
+
+ case 0x2722:
+ if (RFIFOREST(fd) < 86)
+ return 0;
+ change_account_email(fd, id, ip);
+ break;
+
+ case 0x2724:
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ status_change_request(fd);
+ break;
+
+ case 0x2725:
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ ban_request(fd);
+ break;
+
+ case 0x2727:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ change_sex(fd);
+ break;
+
+ case 0x2728:
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ save_account_reg(fd);
+ break;
+
+ case 0x272a:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ unban_request(fd);
+ return 0;
+
+ case 0x272b: // Set account_id to online [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ add_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x272c: // Set account_id to offline [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ remove_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
+ default:
+ #ifdef DEBUG
+ printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
+ #endif
+ session[fd]->eof = 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/login_sql/char_int.h b/src/login_sql/char_int.h
index 3194d13e4..195d1be42 100644
--- a/src/login_sql/char_int.h
+++ b/src/login_sql/char_int.h
@@ -1,2 +1,2 @@
-int char_anti_freeze_system(int, unsigned int, int, int);
-int parse_fromchar(int);
+int char_anti_freeze_system(int, unsigned int, int, int);
+int parse_fromchar(int);
diff --git a/src/login_sql/login_int.c b/src/login_sql/login_int.c
index 3b071f0e7..91dec834e 100644
--- a/src/login_sql/login_int.c
+++ b/src/login_sql/login_int.c
@@ -1,370 +1,370 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "login.h"
-#include "char_int.h"
-
-//----------------------
-// Client requesting login [Edit: Wizputer]
-//----------------------
-void client_request_login(int fd,unsigned char *p ) {
- struct mmo_account account;
- char t_uid[32];
- int server_num = 0,result,i;
-
- if( !servers_connected) {
- WFIFOW(fd,0) = 0x81;
- WFIFOL(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- }
-
- #ifdef DEBUG
- printf("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
- #endif
-
- account.userid = RFIFOP(fd, 6);
- account.passwd = RFIFOP(fd, 30);
-#ifdef PASSWORDENC
- account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
-#else
- account.passwdenc=0;
-#endif
- result=mmo_auth(&account, fd);
-
- jstrescapecpy(t_uid,RFIFOP(fd, 6));
- if(result==-1){
- unsigned char gm_level = isGM(account.account_id);
- if (min_level_to_connect > gm_level || !servers_connected) {
- WFIFOW(fd,0) = 0x81;
- WFIFOL(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- } else {
- if (p[0] != 127) {
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s','100', 'login ok')", loginlog_db, p[0], p[1], p[2], p[3], t_uid);
- sql_query(tmpsql,"client_request_login");
- }
-
- if (gm_level) {
- #ifdef DEBUG
- printf("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
- #endif
- } else {
- #ifdef DEBUG
- printf("Connection of the account '%s' accepted.\n", account.userid);
- #endif
- }
-
- for(i = 0; i < MAX_SERVERS || server_num < servers_connected ; i++)
- if (server_fd[i] >= 0) {
- //Lan check added by Kashy
- if (lan_ip_check(p))
- WFIFOL(fd,47+server_num*32) = inet_addr(lan_char_ip);
- else
- WFIFOL(fd,47+server_num*32) = server[i].ip;
-
- WFIFOW(fd,47+server_num*32+4) = server[i].port;
- memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,47+server_num*32+26) = server[i].users;
- WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,47+server_num*32+30) = server[i].new;
- server_num++;
- }
-
- WFIFOW(fd,0)=0x69;
- WFIFOW(fd,2)=47+32*server_num;
- WFIFOL(fd,4)=account.login_id1;
- WFIFOL(fd,8)=account.account_id;
- WFIFOL(fd,12)=account.login_id2;
- WFIFOL(fd,16)=0;
- memcpy(WFIFOP(fd,20),account.lastlogin,24);
- WFIFOB(fd,46)=account.sex;
- WFIFOSET(fd,47+32*server_num);
-
- if(auth_fifo_pos>=AUTH_FIFO_SIZE)
- auth_fifo_pos=0;
-
- auth_fifo[auth_fifo_pos].account_id=account.account_id;
- auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
- auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
- auth_fifo[auth_fifo_pos].sex=account.sex;
- auth_fifo[auth_fifo_pos].delflag=0;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
- auth_fifo_pos++;
- }
- } else {
- char error[32];
-
- sprintf(tmpsql,"SELECT `error` FROM `errors` WHERE `result`='%d'",result);
- sql_query(tmpsql,"client_request_login");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if ((sql_row = mysql_fetch_row(sql_res))) {
- sprintf(error,sql_row[0]);
- } else {
- sprintf(error,"No Error!");
- }
- }
-
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s', '%d','login failed : %s')", loginlog_db, p[0], p[1], p[2], p[3], t_uid, result, error);
-
-
- sql_query(tmpsql,"client_request_login");
-
- if ((result == 1) && (dynamic_pass_failure_ban != 0)){ // failed password
- sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%d.%d.%d.%d' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
- loginlog_db, p[0], p[1], p[2], p[3], dynamic_pass_failure_ban_time); //how many times filed account? in one ip.
- sql_query(tmpsql,"client_request_login");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if ((sql_row = mysql_fetch_row(sql_res))) {
- if (atoi(sql_row[0]) >= dynamic_pass_failure_ban_how_many ) {
- sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], dynamic_pass_failure_ban_how_long, t_uid);
- sql_query(tmpsql,"client_request_login");
- }
- }
- }
-
-
- mysql_free_result(sql_res);
-
- }
-
- //cannot connect login failed
- memset(WFIFOP(fd,0),'\0',23);
- WFIFOW(fd,0)=0x6a;
- WFIFOB(fd,2)=result-1;
- if (result == 6) { // 6 = Your are Prohibited to log in until %s
- char tmpstr[256];
- strftime(tmpstr, 20, date_format, localtime(&account.ban_until_time));
- tmpstr[19] = '\0';
- memcpy(WFIFOP(fd,3), tmpstr, 20);
- } else { // we send error message
- memcpy(WFIFOP(fd,3), error, 20);
- }
- }
-
- WFIFOSET(fd,23);
-
- RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
-}
-
-//------------------------------------------------------
-// MD5 Key requested for encypted login [Edit: Wizputer
-//------------------------------------------------------
-void md5_key_request(int fd) {
- #ifdef DEBUG
- printf("Request Password key -%s\n",md5key);
- #endif
-
- RFIFOSKIP(fd,2);
- WFIFOW(fd,0)=0x01dc;
- WFIFOW(fd,2)=4+md5keylen;
- memcpy(WFIFOP(fd,4),md5key,md5keylen);
- WFIFOSET(fd,WFIFOW(fd,2));
-}
-
-//----------------------------------------------------
-// Char-server requesting connection [Edit: Wizputer]
-//-----------------------------------------------------
-void char_request_login(int fd, unsigned char *p) {
- struct mmo_account account;
- unsigned char* server_name;
- char t_uid[32];
- int result;
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, p[0], p[1], p[2], p[3], RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
- sql_query(tmpsql,"char_request_login");
-
- #ifdef DEBUG
- printf("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
- RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
- p[0], p[1], p[2], p[3]);
- #endif
-
- account.userid = RFIFOP(fd, 2);
- account.passwd = RFIFOP(fd, 26);
- account.passwdenc = 0;
- server_name = RFIFOP(fd,60);
- result = mmo_auth(&account, fd);
-
- #ifdef DEBUG
- printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
- #endif
-
- if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
- printf("Connection of the char-server '%s' accepted.\n", server_name);
-
- memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
-
- server[account.account_id].ip=RFIFOL(fd,54);
- server[account.account_id].port=RFIFOW(fd,58);
- memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
- server[account.account_id].users=0;
- server[account.account_id].maintenance=RFIFOW(fd,82);
- server[account.account_id].new=RFIFOW(fd,84);
- server_fd[account.account_id]=fd;
-
- if(anti_freeze_enable)
- server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-
- jstrescapecpy(t_uid,server[account.account_id].name);
-
- sprintf(tmpsql,"REPLACE DELAYED INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
- account.account_id, server[account.account_id].name,0);
- sql_query(tmpsql,"char_request_login");
-
- WFIFOW(fd,0)=0x2711;
- WFIFOB(fd,2)=0;
- WFIFOSET(fd,3);
- session[fd]->func_parse=parse_fromchar;
- realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
-
- servers_connected++;
- } else {
- WFIFOW(fd, 0) =0x2711;
- WFIFOB(fd, 2)=3;
- WFIFOSET(fd, 3);
- }
-
- RFIFOSKIP(fd, 86);
-}
-
-//---------------------------------------------
-// Athena Version Info Request [Edit: Wizputer]
-//---------------------------------------------
-void request_athena_info(int fd) {
- #ifdef DEBUG
- printf ("Athena version check...\n");
- #endif
-
- WFIFOW(fd,0)=0x7531;
- WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
- WFIFOB(fd,4)=ATHENA_REVISION;
- WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
- WFIFOW(fd,8)=ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
- RFIFOSKIP(fd,2);
-}
-
-//----------------------------------------------------------------------------------------
-// Default packet parsing (normal players or administation/char-server connection requests)
-//----------------------------------------------------------------------------------------
-int parse_login(int fd) {
- char ip[16];
-
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-
- if (ipban > 0) {
- //ip ban
- //p[0], p[1], p[2], p[3]
- //request DB connection
- //check
- sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
- p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
- sql_query(tmpsql,"parse_login");
-
- if((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {//row fetching
- if (atoi(sql_row[0]) >0) {
- // ip ban ok.
- printf ("packet from banned ip : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', 'unknown','-3', 'ip banned')", loginlog_db, p[0], p[1], p[2], p[3]);
- sql_query(tmpsql,"parse_login");
-
- #ifdef DEBUG
- printf ("close session connection...\n");
- #endif
-
- // close connection
- session[fd]->eof = 1;
- } else {
- #ifdef DEBUG
- printf ("packet from ip (ban check ok) : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
- #endif
- }
- }
- }
-
- mysql_free_result(sql_res);
- }
-
- if (session[fd]->eof) {
- int i;
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++)
- if (server_fd[i] == fd) {
- server_fd[i] = -1;
- servers_connected--;
- }
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- while(RFIFOREST(fd)>=2){
- #ifdef DEBUG_PACKETS
- printf("parse_login : %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- #endif
-
- switch(RFIFOW(fd,0)){
- case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
- if (RFIFOREST(fd) < 26)
- return 0;
- RFIFOSKIP(fd,26);
- break;
-
- case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004)
- if (RFIFOREST(fd) < 18)
- return 0;
- RFIFOSKIP(fd,18);
- break;
-
- case 0x64:
- case 0x01dd:
- if(RFIFOREST(fd)< ((RFIFOW(fd, 0) ==0x64)?55:47))
- return 0;
- client_request_login(fd, p);
- break;
- case 0x01db:
- if (session[fd]->session_data) {
- #ifdef DEBUG
- printf("login: abnormal request of MD5 key (already opened session).\n");
- #endif
- session[fd]->eof = 1;
- return 0;
- }
- md5_key_request(fd);
- break;
-
- case 0x2710:
- if(RFIFOREST(fd)<86)
- return 0;
- char_request_login(fd,p);
- break;
-
- case 0x7530:
- request_athena_info(fd);
- break;
-
- case 0x7532:
- default:
- #ifdef DEBUG
- printf ("End of connection (ip: %s)" RETCODE, ip);
- #endif
- session[fd]->eof = 1;
- return 0;
- }
- }
-
- return 0;
-}
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "login.h"
+#include "char_int.h"
+
+//----------------------
+// Client requesting login [Edit: Wizputer]
+//----------------------
+void client_request_login(int fd,unsigned char *p ) {
+ struct mmo_account account;
+ char t_uid[32];
+ int server_num = 0,result,i;
+
+ if( !servers_connected) {
+ WFIFOW(fd,0) = 0x81;
+ WFIFOL(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ }
+
+ #ifdef DEBUG
+ printf("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
+ #endif
+
+ account.userid = RFIFOP(fd, 6);
+ account.passwd = RFIFOP(fd, 30);
+#ifdef PASSWORDENC
+ account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
+#else
+ account.passwdenc=0;
+#endif
+ result=mmo_auth(&account, fd);
+
+ jstrescapecpy(t_uid,RFIFOP(fd, 6));
+ if(result==-1){
+ unsigned char gm_level = isGM(account.account_id);
+ if (min_level_to_connect > gm_level || !servers_connected) {
+ WFIFOW(fd,0) = 0x81;
+ WFIFOL(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ } else {
+ if (p[0] != 127) {
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s','100', 'login ok')", loginlog_db, p[0], p[1], p[2], p[3], t_uid);
+ sql_query(tmpsql,"client_request_login");
+ }
+
+ if (gm_level) {
+ #ifdef DEBUG
+ printf("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
+ #endif
+ } else {
+ #ifdef DEBUG
+ printf("Connection of the account '%s' accepted.\n", account.userid);
+ #endif
+ }
+
+ for(i = 0; i < MAX_SERVERS || server_num < servers_connected ; i++)
+ if (server_fd[i] >= 0) {
+ //Lan check added by Kashy
+ if (lan_ip_check(p))
+ WFIFOL(fd,47+server_num*32) = inet_addr(lan_char_ip);
+ else
+ WFIFOL(fd,47+server_num*32) = server[i].ip;
+
+ WFIFOW(fd,47+server_num*32+4) = server[i].port;
+ memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
+ WFIFOW(fd,47+server_num*32+26) = server[i].users;
+ WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
+ WFIFOW(fd,47+server_num*32+30) = server[i].new;
+ server_num++;
+ }
+
+ WFIFOW(fd,0)=0x69;
+ WFIFOW(fd,2)=47+32*server_num;
+ WFIFOL(fd,4)=account.login_id1;
+ WFIFOL(fd,8)=account.account_id;
+ WFIFOL(fd,12)=account.login_id2;
+ WFIFOL(fd,16)=0;
+ memcpy(WFIFOP(fd,20),account.lastlogin,24);
+ WFIFOB(fd,46)=account.sex;
+ WFIFOSET(fd,47+32*server_num);
+
+ if(auth_fifo_pos>=AUTH_FIFO_SIZE)
+ auth_fifo_pos=0;
+
+ auth_fifo[auth_fifo_pos].account_id=account.account_id;
+ auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
+ auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
+ auth_fifo[auth_fifo_pos].sex=account.sex;
+ auth_fifo[auth_fifo_pos].delflag=0;
+ auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ auth_fifo_pos++;
+ }
+ } else {
+ char error[32];
+
+ sprintf(tmpsql,"SELECT `error` FROM `errors` WHERE `result`='%d'",result);
+ sql_query(tmpsql,"client_request_login");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if ((sql_row = mysql_fetch_row(sql_res))) {
+ sprintf(error,sql_row[0]);
+ } else {
+ sprintf(error,"No Error!");
+ }
+ }
+
+
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s', '%d','login failed : %s')", loginlog_db, p[0], p[1], p[2], p[3], t_uid, result, error);
+
+
+ sql_query(tmpsql,"client_request_login");
+
+ if ((result == 1) && (dynamic_pass_failure_ban != 0)){ // failed password
+ sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%d.%d.%d.%d' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
+ loginlog_db, p[0], p[1], p[2], p[3], dynamic_pass_failure_ban_time); //how many times filed account? in one ip.
+ sql_query(tmpsql,"client_request_login");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if ((sql_row = mysql_fetch_row(sql_res))) {
+ if (atoi(sql_row[0]) >= dynamic_pass_failure_ban_how_many ) {
+ sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], dynamic_pass_failure_ban_how_long, t_uid);
+ sql_query(tmpsql,"client_request_login");
+ }
+ }
+ }
+
+
+ mysql_free_result(sql_res);
+
+ }
+
+ //cannot connect login failed
+ memset(WFIFOP(fd,0),'\0',23);
+ WFIFOW(fd,0)=0x6a;
+ WFIFOB(fd,2)=result-1;
+ if (result == 6) { // 6 = Your are Prohibited to log in until %s
+ char tmpstr[256];
+ strftime(tmpstr, 20, date_format, localtime(&account.ban_until_time));
+ tmpstr[19] = '\0';
+ memcpy(WFIFOP(fd,3), tmpstr, 20);
+ } else { // we send error message
+ memcpy(WFIFOP(fd,3), error, 20);
+ }
+ }
+
+ WFIFOSET(fd,23);
+
+ RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
+}
+
+//------------------------------------------------------
+// MD5 Key requested for encypted login [Edit: Wizputer
+//------------------------------------------------------
+void md5_key_request(int fd) {
+ #ifdef DEBUG
+ printf("Request Password key -%s\n",md5key);
+ #endif
+
+ RFIFOSKIP(fd,2);
+ WFIFOW(fd,0)=0x01dc;
+ WFIFOW(fd,2)=4+md5keylen;
+ memcpy(WFIFOP(fd,4),md5key,md5keylen);
+ WFIFOSET(fd,WFIFOW(fd,2));
+}
+
+//----------------------------------------------------
+// Char-server requesting connection [Edit: Wizputer]
+//-----------------------------------------------------
+void char_request_login(int fd, unsigned char *p) {
+ struct mmo_account account;
+ unsigned char* server_name;
+ char t_uid[32];
+ int result;
+
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, p[0], p[1], p[2], p[3], RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
+ sql_query(tmpsql,"char_request_login");
+
+ #ifdef DEBUG
+ printf("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
+ RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
+ p[0], p[1], p[2], p[3]);
+ #endif
+
+ account.userid = RFIFOP(fd, 2);
+ account.passwd = RFIFOP(fd, 26);
+ account.passwdenc = 0;
+ server_name = RFIFOP(fd,60);
+ result = mmo_auth(&account, fd);
+
+ #ifdef DEBUG
+ printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
+ #endif
+
+ if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
+ printf("Connection of the char-server '%s' accepted.\n", server_name);
+
+ memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
+
+ server[account.account_id].ip=RFIFOL(fd,54);
+ server[account.account_id].port=RFIFOW(fd,58);
+ memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
+ server[account.account_id].users=0;
+ server[account.account_id].maintenance=RFIFOW(fd,82);
+ server[account.account_id].new=RFIFOW(fd,84);
+ server_fd[account.account_id]=fd;
+
+ if(anti_freeze_enable)
+ server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
+
+ jstrescapecpy(t_uid,server[account.account_id].name);
+
+ sprintf(tmpsql,"REPLACE DELAYED INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
+ account.account_id, server[account.account_id].name,0);
+ sql_query(tmpsql,"char_request_login");
+
+ WFIFOW(fd,0)=0x2711;
+ WFIFOB(fd,2)=0;
+ WFIFOSET(fd,3);
+ session[fd]->func_parse=parse_fromchar;
+ realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
+
+ servers_connected++;
+ } else {
+ WFIFOW(fd, 0) =0x2711;
+ WFIFOB(fd, 2)=3;
+ WFIFOSET(fd, 3);
+ }
+
+ RFIFOSKIP(fd, 86);
+}
+
+//---------------------------------------------
+// Athena Version Info Request [Edit: Wizputer]
+//---------------------------------------------
+void request_athena_info(int fd) {
+ #ifdef DEBUG
+ printf ("Athena version check...\n");
+ #endif
+
+ WFIFOW(fd,0)=0x7531;
+ WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
+ WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
+ WFIFOB(fd,4)=ATHENA_REVISION;
+ WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
+ WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
+ WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
+ WFIFOW(fd,8)=ATHENA_MOD_VERSION;
+ WFIFOSET(fd,10);
+ RFIFOSKIP(fd,2);
+}
+
+//----------------------------------------------------------------------------------------
+// Default packet parsing (normal players or administation/char-server connection requests)
+//----------------------------------------------------------------------------------------
+int parse_login(int fd) {
+ char ip[16];
+
+ unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+
+ if (ipban > 0) {
+ //ip ban
+ //p[0], p[1], p[2], p[3]
+ //request DB connection
+ //check
+ sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
+ p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
+ sql_query(tmpsql,"parse_login");
+
+ if((sql_res = mysql_store_result(&mysql_handle))) {
+ if((sql_row = mysql_fetch_row(sql_res))) {//row fetching
+ if (atoi(sql_row[0]) >0) {
+ // ip ban ok.
+ printf ("packet from banned ip : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
+
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', 'unknown','-3', 'ip banned')", loginlog_db, p[0], p[1], p[2], p[3]);
+ sql_query(tmpsql,"parse_login");
+
+ #ifdef DEBUG
+ printf ("close session connection...\n");
+ #endif
+
+ // close connection
+ session[fd]->eof = 1;
+ } else {
+ #ifdef DEBUG
+ printf ("packet from ip (ban check ok) : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
+ #endif
+ }
+ }
+ }
+
+ mysql_free_result(sql_res);
+ }
+
+ if (session[fd]->eof) {
+ int i;
+ for(i = 0; i < MAX_SERVERS && i < servers_connected; i++)
+ if (server_fd[i] == fd) {
+ server_fd[i] = -1;
+ servers_connected--;
+ }
+ close(fd);
+ delete_session(fd);
+ return 0;
+ }
+
+ while(RFIFOREST(fd)>=2){
+ #ifdef DEBUG_PACKETS
+ printf("parse_login : %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
+ #endif
+
+ switch(RFIFOW(fd,0)){
+ case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
+ if (RFIFOREST(fd) < 26)
+ return 0;
+ RFIFOSKIP(fd,26);
+ break;
+
+ case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004)
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ RFIFOSKIP(fd,18);
+ break;
+
+ case 0x64:
+ case 0x01dd:
+ if(RFIFOREST(fd)< ((RFIFOW(fd, 0) ==0x64)?55:47))
+ return 0;
+ client_request_login(fd, p);
+ break;
+ case 0x01db:
+ if (session[fd]->session_data) {
+ #ifdef DEBUG
+ printf("login: abnormal request of MD5 key (already opened session).\n");
+ #endif
+ session[fd]->eof = 1;
+ return 0;
+ }
+ md5_key_request(fd);
+ break;
+
+ case 0x2710:
+ if(RFIFOREST(fd)<86)
+ return 0;
+ char_request_login(fd,p);
+ break;
+
+ case 0x7530:
+ request_athena_info(fd);
+ break;
+
+ case 0x7532:
+ default:
+ #ifdef DEBUG
+ printf ("End of connection (ip: %s)" RETCODE, ip);
+ #endif
+ session[fd]->eof = 1;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/login_sql/login_int.h b/src/login_sql/login_int.h
index e245d39aa..712585616 100644
--- a/src/login_sql/login_int.h
+++ b/src/login_sql/login_int.h
@@ -1 +1 @@
-int parse_login(int);
+int parse_login(int);
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index 27dbd260f..de05e20ae 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -1,703 +1,703 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-
-#include "../common/socket.h"
-#include "../common/timer.h"
-#include "../common/nullpo.h"
-
-#include "log.h"
-#include "clif.h"
-#include "chrif.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "map.h"
-#include "pc.h"
-#include "skill.h"
-#include "mob.h"
-#include "pet.h"
-#include "battle.h"
-#include "party.h"
-#include "guild.h"
-#include "charcommand.h"
-#include "atcommand.h"
-#include "script.h"
-#include "npc.h"
-#include "trade.h"
-#include "core.h"
-
-static char command_symbol = '#';
-
-static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
-
-#define CCMD_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
-
-CCMD_FUNC(jobchange);
-CCMD_FUNC(petrename);
-CCMD_FUNC(petfriendly);
-CCMD_FUNC(stats);
-CCMD_FUNC(option);
-CCMD_FUNC(save);
-CCMD_FUNC(stats_all);
-CCMD_FUNC(reset);
-
-#ifdef TXT_ONLY
-/* TXT_ONLY */
-
-/* TXT_ONLY */
-#else
-/* SQL-only */
-
-/* SQL Only */
-#endif
-
-/*==========================================
- *CharCommandInfo charcommand_info[]\‘¢‘Ì‚Ì’è‹`
- *------------------------------------------
- */
-
-// First char of commands is configured in charcommand_athena.conf. Leave @ in this list for default value.
-// to set default level, read charcommand_athena.conf first please.
-static CharCommandInfo charcommand_info[] = {
- { CharCommandJobChange, "#job", 60, charcommand_jobchange },
- { CharCommandJobChange, "#jobchange", 60, charcommand_jobchange },
- { CharCommandPetRename, "#petrename", 50, charcommand_petrename },
- { CharCommandPetFriendly, "#petfriendly", 50, charcommand_petfriendly },
- { CharCommandStats, "#stats", 40, charcommand_stats },
- { CharCommandOption, "#option", 60, charcommand_option },
- { CharCommandReset, "#reset", 60, charcommand_reset },
- { CharCommandSave, "#save", 60, charcommand_save },
- { CharCommandStatsAll, "#statsall", 40, charcommand_stats_all },
-
-#ifdef TXT_ONLY
-/* TXT_ONLY */
-
-/* TXT_ONLY */
-#else
-/* SQL-only */
-
-/* SQL Only */
-#endif
-
-// add new commands before this line
- { CharCommand_Unknown, NULL, 1, NULL }
-};
-
-
-int get_charcommand_level(const CharCommandType type) {
- int i;
-
- for (i = 0; charcommand_info[i].type != CharCommand_None; i++)
- if (charcommand_info[i].type == type)
- return charcommand_info[i].level;
-
- return 100; // 100: command can not be used
-}
-
-/*==========================================
- *is_charcommand @ƒRƒ}ƒ“ƒh‚É‘¶Ý‚·‚é‚©‚Ç‚¤‚©Šm”F‚·‚é
- *------------------------------------------
- */
-CharCommandType
-is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl) {
- const char* str = message;
- int s_flag = 0;
- CharCommandInfo info;
- CharCommandType type;
-
- nullpo_retr(CharCommand_None, sd);
-
- if (!message || !*message)
- return CharCommand_None;
-
- memset(&info, 0, sizeof(info));
- str += strlen(sd->status.name);
- while (*str && (isspace(*str) || (s_flag == 0 && *str == ':'))) {
- if (*str == ':')
- s_flag = 1;
- str++;
- }
- if (!*str)
- return CharCommand_None;
-
- type = charcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info);
- if (type != CharCommand_None) {
- char command[100];
- char output[200];
- const char* p = str;
- memset(command, '\0', sizeof(command));
- memset(output, '\0', sizeof(output));
- while (*p && !isspace(*p))
- p++;
- if (p - str >= sizeof(command)) // too long
- return CharCommand_Unknown;
- strncpy(command, str, p - str);
- while (isspace(*p))
- p++;
-
- if (type == CharCommand_Unknown || info.proc == NULL) {
- snprintf(output, sizeof(output),msg_txt(153), command); // %s is Unknown Command.
- clif_displaymessage(fd, output);
- } else {
- if (info.proc(fd, sd, command, p) != 0) {
- // Command can not be executed
- snprintf(output, sizeof(output), msg_txt(154), command); // %s failed.
- clif_displaymessage(fd, output);
- }
- }
-
- return info.type;
- }
-
- return CharCommand_None;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-CharCommandType charcommand(const int level, const char* message, struct CharCommandInfo* info) {
- char* p = (char *)message;
-
- if (!info)
- return CharCommand_None;
- if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd)
- return CharCommand_None;
- if (!p || !*p) {
- fprintf(stderr, "char command message is empty\n");
- return CharCommand_None;
- }
-
- if (*p == command_symbol) { // check first char.
- char command[101];
- int i = 0;
- memset(info, 0, sizeof(CharCommandInfo));
- sscanf(p, "%100s", command);
- command[sizeof(command)-1] = '\0';
-
- while (charcommand_info[i].type != CharCommand_Unknown) {
- if (strcmpi(command+1, charcommand_info[i].command+1) == 0 && level >= charcommand_info[i].level) {
- p[0] = charcommand_info[i].command[0]; // set correct first symbol for after.
- break;
- }
- i++;
- }
-
- if (charcommand_info[i].type == CharCommand_Unknown) {
- // doesn't return Unknown if player is normal player (display the text, not display: unknown command)
- if (level == 0)
- return CharCommand_None;
- else
- return CharCommand_Unknown;
- }
- memcpy(info, &charcommand_info[i], sizeof charcommand_info[i]);
- } else {
- return CharCommand_None;
- }
-
- return info->type;
-}
-
-
-/*==========================================
- *
- *------------------------------------------
- */
-static CharCommandInfo* get_charcommandinfo_byname(const char* name) {
- int i;
-
- for (i = 0; charcommand_info[i].type != CharCommand_Unknown; i++)
- if (strcmpi(charcommand_info[i].command + 1, name) == 0)
- return &charcommand_info[i];
-
- return NULL;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_config_read(const char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- CharCommandInfo* p;
- FILE* fp;
-
- if ((fp = fopen(cfgName, "r")) == NULL) {
- printf("CharCommands configuration file not found: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line)-1, fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
- continue;
- p = get_charcommandinfo_byname(w1);
- if (p != NULL) {
- p->level = atoi(w2);
- if (p->level > 100)
- p->level = 100;
- else if (p->level < 0)
- p->level = 0;
- }
-
- if (strcmpi(w1, "import") == 0)
- charcommand_config_read(w2);
- else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 &&
- w2[0] != '/' && // symbol of standard ragnarok GM commands
- w2[0] != '%' && // symbol of party chat speaking
- w2[0] != '@') // symbol for @commands
- command_symbol = w2[0];
- }
- fclose(fp);
-
- return 0;
-}
-
-/*==========================================
- * ‘ÎÛƒLƒƒƒ‰ƒNƒ^[‚ð“]E‚³‚¹‚é upperŽw’è‚Å“]¶‚â—{Žq‚à‰Â”\
- *------------------------------------------
- */
-int charcommand_jobchange(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char character[100];
- struct map_session_data* pl_sd;
- int job = 0, upper = -1;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message) {
- clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>).");
- return -1;
- }
-
- if (sscanf(message, "%d %d %99[^\n]", &job, &upper, character) < 3) { //upperŽw’肵‚Ä‚ ‚é
- upper = -1;
- if (sscanf(message, "%d %99[^\n]", &job, character) < 2) { //upperŽw’肵‚Ä‚È‚¢ã‚ɉ½‚©‘«‚è‚È‚¢
- clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>).");
- return -1;
- }
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job only to lower or same level
- if ((job >= 0 && job < MAX_PC_CLASS)) {
-
- // fix pecopeco display
- if ((job != 13 && job != 21 && job != 4014 && job != 4022)) {
- if (pc_isriding(sd)) {
- if (pl_sd->status.class == 13)
- pl_sd->status.class = pl_sd->view_class = 7;
- if (pl_sd->status.class == 21)
- pl_sd->status.class = pl_sd->view_class = 14;
- if (pl_sd->status.class == 4014)
- pl_sd->status.class = pl_sd->view_class = 4008;
- if (pl_sd->status.class == 4022)
- pl_sd->status.class = pl_sd->view_class = 4015;
- pl_sd->status.option &= ~0x0020;
- clif_changeoption(&pl_sd->bl);
- pc_calcstatus(pl_sd, 0);
- }
- } else {
- if (!pc_isriding(sd)) {
- if (job == 13)
- job = 7;
- if (job == 21)
- job = 14;
- if (job == 4014)
- job = 4008;
- if (job == 4022)
- job = 4015;
- }
- }
-
- if (pc_jobchange(pl_sd, job, upper) == 0)
- clif_displaymessage(fd, msg_table[48]); // Character's job changed.
- else {
- clif_displaymessage(fd, msg_table[192]); // Impossible to change the character's job.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[49]); // Invalid job ID.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_petrename(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char character[100];
- struct map_session_data *pl_sd;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
- clif_displaymessage(fd, "Please, enter a player name (usage: #petrename <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
- if (pl_sd->pet.rename_flag != 0) {
- pl_sd->pet.rename_flag = 0;
- intif_save_petdata(pl_sd->status.account_id, &pl_sd->pet);
- clif_send_petstatus(pl_sd);
- clif_displaymessage(fd, msg_table[189]); // This player can now rename his/her pet.
- } else {
- clif_displaymessage(fd, msg_table[190]); // This player can already rename his/her pet.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_petfriendly(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- int friendly = 0;
- int t = 0;
- char character[100];
- struct map_session_data *pl_sd;
-
- memset(character, '\0', sizeof(character));
- if (!message || !*message || sscanf(message,"%d %s",&friendly,character) < 2) {
- clif_displaymessage(fd, "Please, enter a valid value (usage: "
- "#petfriendly <0-1000> <player>).");
- return -1;
- }
-
- if (((pl_sd = map_nick2sd(character)) != NULL) && pc_isGM(sd)>pc_isGM(pl_sd)) {
- if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
- if (friendly >= 0 && friendly <= 1000) {
- if (friendly != pl_sd->pet.intimate) {
- t = pl_sd->pet.intimate;
- pl_sd->pet.intimate = friendly;
- clif_send_petstatus(pl_sd);
- clif_pet_emotion(pl_sd->pd,0);
- if (battle_config.pet_status_support) {
- if ((pl_sd->pet.intimate > 0 && t <= 0) ||
- (pl_sd->pet.intimate <= 0 && t > 0)) {
- if (pl_sd->bl.prev != NULL)
- pc_calcstatus(pl_sd, 0);
- else
- pc_calcstatus(pl_sd, 2);
- }
- }
- clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed!
- clif_displaymessage(sd->fd, msg_table[182]); // Pet friendly value changed!
- } else {
- clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
- return -1;
- }
- } else {
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_txt(3)); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_stats(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char character[100];
- char job_jobname[100];
- char output[200];
- struct map_session_data *pl_sd;
- int i;
-
- memset(character, '\0', sizeof(character));
- memset(job_jobname, '\0', sizeof(job_jobname));
- memset(output, '\0', sizeof(output));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
- clif_displaymessage(fd, "Please, enter a player name (usage: #stats <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- struct {
- const char* format;
- int value;
- } output_table[] = {
- { "Base Level - %d", pl_sd->status.base_level },
- { job_jobname, pl_sd->status.job_level },
- { "Hp - %d", pl_sd->status.hp },
- { "MaxHp - %d", pl_sd->status.max_hp },
- { "Sp - %d", pl_sd->status.sp },
- { "MaxSp - %d", pl_sd->status.max_sp },
- { "Str - %3d", pl_sd->status.str },
- { "Agi - %3d", pl_sd->status.agi },
- { "Vit - %3d", pl_sd->status.vit },
- { "Int - %3d", pl_sd->status.int_ },
- { "Dex - %3d", pl_sd->status.dex },
- { "Luk - %3d", pl_sd->status.luk },
- { "Zeny - %d", pl_sd->status.zeny },
- { NULL, 0 }
- };
- sprintf(job_jobname, "Job - %s %s", job_name(pl_sd->status.class), "(level %d)");
- sprintf(output, msg_table[53], pl_sd->status.name); // '%s' stats:
- clif_displaymessage(fd, output);
- for (i = 0; output_table[i].format != NULL; i++) {
- sprintf(output, output_table[i].format, output_table[i].value);
- clif_displaymessage(fd, output);
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- * Character Reset
- *------------------------------------------
- */
-int charcommand_reset(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char character[100];
- char output[200];
- struct map_session_data *pl_sd;
-
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
- clif_displaymessage(fd, "Please, enter a player name (usage: #reset <charname>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset a character only for lower or same GM level
- pc_resetstate(pl_sd);
- pc_resetskill(pl_sd);
- sprintf(output, msg_table[208], character); // '%s' skill and stats points reseted!
- clif_displaymessage(fd, output);
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_option(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char character[100];
- int opt1 = 0, opt2 = 0, opt3 = 0;
- struct map_session_data* pl_sd;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message ||
- sscanf(message, "%d %d %d %99[^\n]", &opt1, &opt2, &opt3, character) < 4 ||
- opt1 < 0 || opt2 < 0 || opt3 < 0) {
- clif_displaymessage(fd, "Please, enter valid options and a player name (usage: #option <param1> <param2> <param3> <charname>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change option only to lower or same level
- pl_sd->opt1 = opt1;
- pl_sd->opt2 = opt2;
- pl_sd->status.option = opt3;
- // fix pecopeco display
- if (pl_sd->status.class == 13 || pl_sd->status.class == 21 || pl_sd->status.class == 4014 || pl_sd->status.class == 4022) {
- if (!pc_isriding(pl_sd)) { // pl_sd have the new value...
- if (pl_sd->status.class == 13)
- pl_sd->status.class = pl_sd->view_class = 7;
- else if (pl_sd->status.class == 21)
- pl_sd->status.class = pl_sd->view_class = 14;
- else if (pl_sd->status.class == 4014)
- pl_sd->status.class = pl_sd->view_class = 4008;
- else if (pl_sd->status.class == 4022)
- pl_sd->status.class = pl_sd->view_class = 4015;
- }
- } else {
- if (pc_isriding(pl_sd)) { // pl_sd have the new value...
- if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
- pl_sd->status.option &= ~0x0020;
- } else {
- if (pl_sd->status.class == 7)
- pl_sd->status.class = pl_sd->view_class = 13;
- else if (pl_sd->status.class == 14)
- pl_sd->status.class = pl_sd->view_class = 21;
- else if (pl_sd->status.class == 4008)
- pl_sd->status.class = pl_sd->view_class = 4014;
- else if (pl_sd->status.class == 4015)
- pl_sd->status.class = pl_sd->view_class = 4022;
- else
- pl_sd->status.option &= ~0x0020;
- }
- }
- }
- clif_changeoption(&pl_sd->bl);
- pc_calcstatus(pl_sd, 0);
- clif_displaymessage(fd, msg_table[58]); // Character's options changed.
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-int charcommand_save(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char map_name[100];
- char character[100];
- struct map_session_data* pl_sd;
- int x = 0, y = 0;
- int m;
-
- memset(map_name, '\0', sizeof(map_name));
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4 || x < 0 || y < 0) {
- clif_displaymessage(fd, "Please, enter a valid save point and a player name (usage: #save <map> <x> <y> <charname>).");
- return -1;
- }
-
- if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
- strcat(map_name, ".gat");
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change save point only to lower or same gm level
- m = map_mapname2mapid(map_name);
- if (m < 0) {
- clif_displaymessage(fd, msg_table[1]); // Map not found.
- return -1;
- } else {
- if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to set this map as a save map.");
- return -1;
- }
- pc_setsavepoint(pl_sd, map_name, x, y);
- clif_displaymessage(fd, msg_table[57]); // Character's respawn point changed.
- }
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-//** Character Stats All by fritz
-int charcommand_stats_all(const int fd, struct map_session_data* sd, const char* command, const char* message)
-{
- char output[1024], gmlevel[1024];
- int i;
- int count;
- struct map_session_data *pl_sd;
-
- memset(output, '\0', sizeof(output));
- memset(gmlevel, '\0', sizeof(gmlevel));
-
- count = 0;
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
-
- if (pc_isGM(pl_sd) > 0)
- sprintf(gmlevel, "| GM Lvl: %d", pc_isGM(pl_sd));
- else
- sprintf(gmlevel, " ");
-
- sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp);
- clif_displaymessage(fd, output);
- sprintf(output, "STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s", pl_sd->status.str, pl_sd->status.agi, pl_sd->status.vit, pl_sd->status.int_, pl_sd->status.dex, pl_sd->status.luk, pl_sd->status.zeny, gmlevel);
- clif_displaymessage(fd, output);
- clif_displaymessage(fd, "--------");
- count++;
- }
- }
-
- if (count == 0)
- clif_displaymessage(fd, msg_table[28]); // No player found.
- else if (count == 1)
- clif_displaymessage(fd, msg_table[29]); // 1 player found.
- else {
- sprintf(output, msg_table[30], count); // %d players found.
- clif_displaymessage(fd, output);
- }
-
- return 0;
-}
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "../common/nullpo.h"
+
+#include "log.h"
+#include "clif.h"
+#include "chrif.h"
+#include "intif.h"
+#include "itemdb.h"
+#include "map.h"
+#include "pc.h"
+#include "skill.h"
+#include "mob.h"
+#include "pet.h"
+#include "battle.h"
+#include "party.h"
+#include "guild.h"
+#include "charcommand.h"
+#include "atcommand.h"
+#include "script.h"
+#include "npc.h"
+#include "trade.h"
+#include "core.h"
+
+static char command_symbol = '#';
+
+static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
+
+#define CCMD_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
+
+CCMD_FUNC(jobchange);
+CCMD_FUNC(petrename);
+CCMD_FUNC(petfriendly);
+CCMD_FUNC(stats);
+CCMD_FUNC(option);
+CCMD_FUNC(save);
+CCMD_FUNC(stats_all);
+CCMD_FUNC(reset);
+
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+
+/* TXT_ONLY */
+#else
+/* SQL-only */
+
+/* SQL Only */
+#endif
+
+/*==========================================
+ *CharCommandInfo charcommand_info[]\‘¢‘Ì‚Ì’è‹`
+ *------------------------------------------
+ */
+
+// First char of commands is configured in charcommand_athena.conf. Leave @ in this list for default value.
+// to set default level, read charcommand_athena.conf first please.
+static CharCommandInfo charcommand_info[] = {
+ { CharCommandJobChange, "#job", 60, charcommand_jobchange },
+ { CharCommandJobChange, "#jobchange", 60, charcommand_jobchange },
+ { CharCommandPetRename, "#petrename", 50, charcommand_petrename },
+ { CharCommandPetFriendly, "#petfriendly", 50, charcommand_petfriendly },
+ { CharCommandStats, "#stats", 40, charcommand_stats },
+ { CharCommandOption, "#option", 60, charcommand_option },
+ { CharCommandReset, "#reset", 60, charcommand_reset },
+ { CharCommandSave, "#save", 60, charcommand_save },
+ { CharCommandStatsAll, "#statsall", 40, charcommand_stats_all },
+
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+
+/* TXT_ONLY */
+#else
+/* SQL-only */
+
+/* SQL Only */
+#endif
+
+// add new commands before this line
+ { CharCommand_Unknown, NULL, 1, NULL }
+};
+
+
+int get_charcommand_level(const CharCommandType type) {
+ int i;
+
+ for (i = 0; charcommand_info[i].type != CharCommand_None; i++)
+ if (charcommand_info[i].type == type)
+ return charcommand_info[i].level;
+
+ return 100; // 100: command can not be used
+}
+
+/*==========================================
+ *is_charcommand @ƒRƒ}ƒ“ƒh‚É‘¶Ý‚·‚é‚©‚Ç‚¤‚©Šm”F‚·‚é
+ *------------------------------------------
+ */
+CharCommandType
+is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl) {
+ const char* str = message;
+ int s_flag = 0;
+ CharCommandInfo info;
+ CharCommandType type;
+
+ nullpo_retr(CharCommand_None, sd);
+
+ if (!message || !*message)
+ return CharCommand_None;
+
+ memset(&info, 0, sizeof(info));
+ str += strlen(sd->status.name);
+ while (*str && (isspace(*str) || (s_flag == 0 && *str == ':'))) {
+ if (*str == ':')
+ s_flag = 1;
+ str++;
+ }
+ if (!*str)
+ return CharCommand_None;
+
+ type = charcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info);
+ if (type != CharCommand_None) {
+ char command[100];
+ char output[200];
+ const char* p = str;
+ memset(command, '\0', sizeof(command));
+ memset(output, '\0', sizeof(output));
+ while (*p && !isspace(*p))
+ p++;
+ if (p - str >= sizeof(command)) // too long
+ return CharCommand_Unknown;
+ strncpy(command, str, p - str);
+ while (isspace(*p))
+ p++;
+
+ if (type == CharCommand_Unknown || info.proc == NULL) {
+ snprintf(output, sizeof(output),msg_txt(153), command); // %s is Unknown Command.
+ clif_displaymessage(fd, output);
+ } else {
+ if (info.proc(fd, sd, command, p) != 0) {
+ // Command can not be executed
+ snprintf(output, sizeof(output), msg_txt(154), command); // %s failed.
+ clif_displaymessage(fd, output);
+ }
+ }
+
+ return info.type;
+ }
+
+ return CharCommand_None;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+CharCommandType charcommand(const int level, const char* message, struct CharCommandInfo* info) {
+ char* p = (char *)message;
+
+ if (!info)
+ return CharCommand_None;
+ if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd)
+ return CharCommand_None;
+ if (!p || !*p) {
+ fprintf(stderr, "char command message is empty\n");
+ return CharCommand_None;
+ }
+
+ if (*p == command_symbol) { // check first char.
+ char command[101];
+ int i = 0;
+ memset(info, 0, sizeof(CharCommandInfo));
+ sscanf(p, "%100s", command);
+ command[sizeof(command)-1] = '\0';
+
+ while (charcommand_info[i].type != CharCommand_Unknown) {
+ if (strcmpi(command+1, charcommand_info[i].command+1) == 0 && level >= charcommand_info[i].level) {
+ p[0] = charcommand_info[i].command[0]; // set correct first symbol for after.
+ break;
+ }
+ i++;
+ }
+
+ if (charcommand_info[i].type == CharCommand_Unknown) {
+ // doesn't return Unknown if player is normal player (display the text, not display: unknown command)
+ if (level == 0)
+ return CharCommand_None;
+ else
+ return CharCommand_Unknown;
+ }
+ memcpy(info, &charcommand_info[i], sizeof charcommand_info[i]);
+ } else {
+ return CharCommand_None;
+ }
+
+ return info->type;
+}
+
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+static CharCommandInfo* get_charcommandinfo_byname(const char* name) {
+ int i;
+
+ for (i = 0; charcommand_info[i].type != CharCommand_Unknown; i++)
+ if (strcmpi(charcommand_info[i].command + 1, name) == 0)
+ return &charcommand_info[i];
+
+ return NULL;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_config_read(const char *cfgName) {
+ char line[1024], w1[1024], w2[1024];
+ CharCommandInfo* p;
+ FILE* fp;
+
+ if ((fp = fopen(cfgName, "r")) == NULL) {
+ printf("CharCommands configuration file not found: %s\n", cfgName);
+ return 1;
+ }
+
+ while (fgets(line, sizeof(line)-1, fp)) {
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+
+ if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
+ continue;
+ p = get_charcommandinfo_byname(w1);
+ if (p != NULL) {
+ p->level = atoi(w2);
+ if (p->level > 100)
+ p->level = 100;
+ else if (p->level < 0)
+ p->level = 0;
+ }
+
+ if (strcmpi(w1, "import") == 0)
+ charcommand_config_read(w2);
+ else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 &&
+ w2[0] != '/' && // symbol of standard ragnarok GM commands
+ w2[0] != '%' && // symbol of party chat speaking
+ w2[0] != '@') // symbol for @commands
+ command_symbol = w2[0];
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+/*==========================================
+ * ‘ÎÛƒLƒƒƒ‰ƒNƒ^[‚ð“]E‚³‚¹‚é upperŽw’è‚Å“]¶‚â—{Žq‚à‰Â”\
+ *------------------------------------------
+ */
+int charcommand_jobchange(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char character[100];
+ struct map_session_data* pl_sd;
+ int job = 0, upper = -1;
+
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>).");
+ return -1;
+ }
+
+ if (sscanf(message, "%d %d %99[^\n]", &job, &upper, character) < 3) { //upperŽw’肵‚Ä‚ ‚é
+ upper = -1;
+ if (sscanf(message, "%d %99[^\n]", &job, character) < 2) { //upperŽw’肵‚Ä‚È‚¢ã‚ɉ½‚©‘«‚è‚È‚¢
+ clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>).");
+ return -1;
+ }
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job only to lower or same level
+ if ((job >= 0 && job < MAX_PC_CLASS)) {
+
+ // fix pecopeco display
+ if ((job != 13 && job != 21 && job != 4014 && job != 4022)) {
+ if (pc_isriding(sd)) {
+ if (pl_sd->status.class == 13)
+ pl_sd->status.class = pl_sd->view_class = 7;
+ if (pl_sd->status.class == 21)
+ pl_sd->status.class = pl_sd->view_class = 14;
+ if (pl_sd->status.class == 4014)
+ pl_sd->status.class = pl_sd->view_class = 4008;
+ if (pl_sd->status.class == 4022)
+ pl_sd->status.class = pl_sd->view_class = 4015;
+ pl_sd->status.option &= ~0x0020;
+ clif_changeoption(&pl_sd->bl);
+ pc_calcstatus(pl_sd, 0);
+ }
+ } else {
+ if (!pc_isriding(sd)) {
+ if (job == 13)
+ job = 7;
+ if (job == 21)
+ job = 14;
+ if (job == 4014)
+ job = 4008;
+ if (job == 4022)
+ job = 4015;
+ }
+ }
+
+ if (pc_jobchange(pl_sd, job, upper) == 0)
+ clif_displaymessage(fd, msg_table[48]); // Character's job changed.
+ else {
+ clif_displaymessage(fd, msg_table[192]); // Impossible to change the character's job.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[49]); // Invalid job ID.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_petrename(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char character[100];
+ struct map_session_data *pl_sd;
+
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ clif_displaymessage(fd, "Please, enter a player name (usage: #petrename <char name>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
+ if (pl_sd->pet.rename_flag != 0) {
+ pl_sd->pet.rename_flag = 0;
+ intif_save_petdata(pl_sd->status.account_id, &pl_sd->pet);
+ clif_send_petstatus(pl_sd);
+ clif_displaymessage(fd, msg_table[189]); // This player can now rename his/her pet.
+ } else {
+ clif_displaymessage(fd, msg_table[190]); // This player can already rename his/her pet.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_petfriendly(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int friendly = 0;
+ int t = 0;
+ char character[100];
+ struct map_session_data *pl_sd;
+
+ memset(character, '\0', sizeof(character));
+ if (!message || !*message || sscanf(message,"%d %s",&friendly,character) < 2) {
+ clif_displaymessage(fd, "Please, enter a valid value (usage: "
+ "#petfriendly <0-1000> <player>).");
+ return -1;
+ }
+
+ if (((pl_sd = map_nick2sd(character)) != NULL) && pc_isGM(sd)>pc_isGM(pl_sd)) {
+ if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
+ if (friendly >= 0 && friendly <= 1000) {
+ if (friendly != pl_sd->pet.intimate) {
+ t = pl_sd->pet.intimate;
+ pl_sd->pet.intimate = friendly;
+ clif_send_petstatus(pl_sd);
+ clif_pet_emotion(pl_sd->pd,0);
+ if (battle_config.pet_status_support) {
+ if ((pl_sd->pet.intimate > 0 && t <= 0) ||
+ (pl_sd->pet.intimate <= 0 && t > 0)) {
+ if (pl_sd->bl.prev != NULL)
+ pc_calcstatus(pl_sd, 0);
+ else
+ pc_calcstatus(pl_sd, 2);
+ }
+ }
+ clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed!
+ clif_displaymessage(sd->fd, msg_table[182]); // Pet friendly value changed!
+ } else {
+ clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_txt(3)); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_stats(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char character[100];
+ char job_jobname[100];
+ char output[200];
+ struct map_session_data *pl_sd;
+ int i;
+
+ memset(character, '\0', sizeof(character));
+ memset(job_jobname, '\0', sizeof(job_jobname));
+ memset(output, '\0', sizeof(output));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ clif_displaymessage(fd, "Please, enter a player name (usage: #stats <char name>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ struct {
+ const char* format;
+ int value;
+ } output_table[] = {
+ { "Base Level - %d", pl_sd->status.base_level },
+ { job_jobname, pl_sd->status.job_level },
+ { "Hp - %d", pl_sd->status.hp },
+ { "MaxHp - %d", pl_sd->status.max_hp },
+ { "Sp - %d", pl_sd->status.sp },
+ { "MaxSp - %d", pl_sd->status.max_sp },
+ { "Str - %3d", pl_sd->status.str },
+ { "Agi - %3d", pl_sd->status.agi },
+ { "Vit - %3d", pl_sd->status.vit },
+ { "Int - %3d", pl_sd->status.int_ },
+ { "Dex - %3d", pl_sd->status.dex },
+ { "Luk - %3d", pl_sd->status.luk },
+ { "Zeny - %d", pl_sd->status.zeny },
+ { NULL, 0 }
+ };
+ sprintf(job_jobname, "Job - %s %s", job_name(pl_sd->status.class), "(level %d)");
+ sprintf(output, msg_table[53], pl_sd->status.name); // '%s' stats:
+ clif_displaymessage(fd, output);
+ for (i = 0; output_table[i].format != NULL; i++) {
+ sprintf(output, output_table[i].format, output_table[i].value);
+ clif_displaymessage(fd, output);
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * Character Reset
+ *------------------------------------------
+ */
+int charcommand_reset(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char character[100];
+ char output[200];
+ struct map_session_data *pl_sd;
+
+ memset(character, '\0', sizeof(character));
+ memset(output, '\0', sizeof(output));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ clif_displaymessage(fd, "Please, enter a player name (usage: #reset <charname>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset a character only for lower or same GM level
+ pc_resetstate(pl_sd);
+ pc_resetskill(pl_sd);
+ sprintf(output, msg_table[208], character); // '%s' skill and stats points reseted!
+ clif_displaymessage(fd, output);
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_option(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char character[100];
+ int opt1 = 0, opt2 = 0, opt3 = 0;
+ struct map_session_data* pl_sd;
+
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message ||
+ sscanf(message, "%d %d %d %99[^\n]", &opt1, &opt2, &opt3, character) < 4 ||
+ opt1 < 0 || opt2 < 0 || opt3 < 0) {
+ clif_displaymessage(fd, "Please, enter valid options and a player name (usage: #option <param1> <param2> <param3> <charname>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change option only to lower or same level
+ pl_sd->opt1 = opt1;
+ pl_sd->opt2 = opt2;
+ pl_sd->status.option = opt3;
+ // fix pecopeco display
+ if (pl_sd->status.class == 13 || pl_sd->status.class == 21 || pl_sd->status.class == 4014 || pl_sd->status.class == 4022) {
+ if (!pc_isriding(pl_sd)) { // pl_sd have the new value...
+ if (pl_sd->status.class == 13)
+ pl_sd->status.class = pl_sd->view_class = 7;
+ else if (pl_sd->status.class == 21)
+ pl_sd->status.class = pl_sd->view_class = 14;
+ else if (pl_sd->status.class == 4014)
+ pl_sd->status.class = pl_sd->view_class = 4008;
+ else if (pl_sd->status.class == 4022)
+ pl_sd->status.class = pl_sd->view_class = 4015;
+ }
+ } else {
+ if (pc_isriding(pl_sd)) { // pl_sd have the new value...
+ if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
+ pl_sd->status.option &= ~0x0020;
+ } else {
+ if (pl_sd->status.class == 7)
+ pl_sd->status.class = pl_sd->view_class = 13;
+ else if (pl_sd->status.class == 14)
+ pl_sd->status.class = pl_sd->view_class = 21;
+ else if (pl_sd->status.class == 4008)
+ pl_sd->status.class = pl_sd->view_class = 4014;
+ else if (pl_sd->status.class == 4015)
+ pl_sd->status.class = pl_sd->view_class = 4022;
+ else
+ pl_sd->status.option &= ~0x0020;
+ }
+ }
+ }
+ clif_changeoption(&pl_sd->bl);
+ pc_calcstatus(pl_sd, 0);
+ clif_displaymessage(fd, msg_table[58]); // Character's options changed.
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_save(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char map_name[100];
+ char character[100];
+ struct map_session_data* pl_sd;
+ int x = 0, y = 0;
+ int m;
+
+ memset(map_name, '\0', sizeof(map_name));
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4 || x < 0 || y < 0) {
+ clif_displaymessage(fd, "Please, enter a valid save point and a player name (usage: #save <map> <x> <y> <charname>).");
+ return -1;
+ }
+
+ if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
+ strcat(map_name, ".gat");
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change save point only to lower or same gm level
+ m = map_mapname2mapid(map_name);
+ if (m < 0) {
+ clif_displaymessage(fd, msg_table[1]); // Map not found.
+ return -1;
+ } else {
+ if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, "You are not authorised to set this map as a save map.");
+ return -1;
+ }
+ pc_setsavepoint(pl_sd, map_name, x, y);
+ clif_displaymessage(fd, msg_table[57]); // Character's respawn point changed.
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+//** Character Stats All by fritz
+int charcommand_stats_all(const int fd, struct map_session_data* sd, const char* command, const char* message)
+{
+ char output[1024], gmlevel[1024];
+ int i;
+ int count;
+ struct map_session_data *pl_sd;
+
+ memset(output, '\0', sizeof(output));
+ memset(gmlevel, '\0', sizeof(gmlevel));
+
+ count = 0;
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+
+ if (pc_isGM(pl_sd) > 0)
+ sprintf(gmlevel, "| GM Lvl: %d", pc_isGM(pl_sd));
+ else
+ sprintf(gmlevel, " ");
+
+ sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp);
+ clif_displaymessage(fd, output);
+ sprintf(output, "STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s", pl_sd->status.str, pl_sd->status.agi, pl_sd->status.vit, pl_sd->status.int_, pl_sd->status.dex, pl_sd->status.luk, pl_sd->status.zeny, gmlevel);
+ clif_displaymessage(fd, output);
+ clif_displaymessage(fd, "--------");
+ count++;
+ }
+ }
+
+ if (count == 0)
+ clif_displaymessage(fd, msg_table[28]); // No player found.
+ else if (count == 1)
+ clif_displaymessage(fd, msg_table[29]); // 1 player found.
+ else {
+ sprintf(output, msg_table[30], count); // %d players found.
+ clif_displaymessage(fd, output);
+ }
+
+ return 0;
+}
+
diff --git a/src/map/charcommand.h b/src/map/charcommand.h
index 8fb17fb64..11babb816 100644
--- a/src/map/charcommand.h
+++ b/src/map/charcommand.h
@@ -1,50 +1,50 @@
-#ifndef _CHARCOMMAND_H_
-#define _CHARCOMMAND_H_
-
-enum CharCommandType {
- CharCommand_None = -1,
- CharCommandJobChange,
- CharCommandPetRename,
- CharCommandPetFriendly,
- CharCommandReset,
- CharCommandStats,
- CharCommandOption,
- CharCommandSave,
- CharCommandStatsAll,
-
-#ifdef TXT_ONLY
-/* TXT_ONLY */
-
-/* TXT_ONLY */
-#else
-/* SQL-only */
-
-/* SQL Only */
-#endif
-
- // End. No more commans after this line.
- CharCommand_Unknown,
- CharCommand_MAX
-};
-
-typedef enum CharCommandType CharCommandType;
-
-typedef struct CharCommandInfo {
- CharCommandType type;
- const char* command;
- int level;
- int (*proc)(const int, struct map_session_data*,
- const char* command, const char* message);
-} CharCommandInfo;
-
-CharCommandType
-is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl);
-
-CharCommandType charcommand(
- const int level, const char* message, CharCommandInfo* info);
-int get_charcommand_level(const CharCommandType type);
-
-int charcommand_config_read(const char *cfgName);
-
-#endif
-
+#ifndef _CHARCOMMAND_H_
+#define _CHARCOMMAND_H_
+
+enum CharCommandType {
+ CharCommand_None = -1,
+ CharCommandJobChange,
+ CharCommandPetRename,
+ CharCommandPetFriendly,
+ CharCommandReset,
+ CharCommandStats,
+ CharCommandOption,
+ CharCommandSave,
+ CharCommandStatsAll,
+
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+
+/* TXT_ONLY */
+#else
+/* SQL-only */
+
+/* SQL Only */
+#endif
+
+ // End. No more commans after this line.
+ CharCommand_Unknown,
+ CharCommand_MAX
+};
+
+typedef enum CharCommandType CharCommandType;
+
+typedef struct CharCommandInfo {
+ CharCommandType type;
+ const char* command;
+ int level;
+ int (*proc)(const int, struct map_session_data*,
+ const char* command, const char* message);
+} CharCommandInfo;
+
+CharCommandType
+is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl);
+
+CharCommandType charcommand(
+ const int level, const char* message, CharCommandInfo* info);
+int get_charcommand_level(const CharCommandType type);
+
+int charcommand_config_read(const char *cfgName);
+
+#endif
+
diff --git a/src/webserver/Changelog.txt b/src/webserver/Changelog.txt
index a3a63b35a..e4d38bac0 100644
--- a/src/webserver/Changelog.txt
+++ b/src/webserver/Changelog.txt
@@ -1,3 +1,3 @@
-Date Added
-12/3
+Date Added
+12/3
* Creation of eAthena Web Server v2 [MC Cameri] \ No newline at end of file
diff --git a/src/webserver/Makefile b/src/webserver/Makefile
index 6ceff7e20..000754036 100644
--- a/src/webserver/Makefile
+++ b/src/webserver/Makefile
@@ -1,32 +1,32 @@
-CC = gcc -pipe
-MAKE = make
-OPT = -g -O2 -ffast-math
-
-ifeq ($(findstring CYGWIN,$(PLATFORM)), CYGWIN)
-CFLAGS = $(OPT) -Wall -I../common
-else
-CFLAGS = $(OPT) -Wall -I../common
-endif
-
-OBJ = main.o webserver.o ../common/showmsg.o
-LINKOBJ = main.o webserver.o ../common/showmsg.o
-
-all: clean webserver run
-
-clean:
- rm -f *.o webserver.exe ../common/showmsg.o
-
-webserver: main.o webserver.o ../common/showmsg.o
- $(CC) $(OPT) -o "Webserver.exe" $(OBJ)
-
-main.o: main.c
- $(CC) $(OPT) -c main.c -o main.o $(CFLAGS)
-
-webserver.o: webserver.c
- $(CC) $(OPT) -c webserver.c -o webserver.o $(CFLAGS)
-
-../common/showmsg.o: ../common/showmsg.c
- $(CC) $(OPT) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
-
-run:
- ./webserver
+CC = gcc -pipe
+MAKE = make
+OPT = -g -O2 -ffast-math
+
+ifeq ($(findstring CYGWIN,$(PLATFORM)), CYGWIN)
+CFLAGS = $(OPT) -Wall -I../common
+else
+CFLAGS = $(OPT) -Wall -I../common
+endif
+
+OBJ = main.o webserver.o ../common/showmsg.o
+LINKOBJ = main.o webserver.o ../common/showmsg.o
+
+all: clean webserver run
+
+clean:
+ rm -f *.o webserver.exe ../common/showmsg.o
+
+webserver: main.o webserver.o ../common/showmsg.o
+ $(CC) $(OPT) -o "Webserver.exe" $(OBJ)
+
+main.o: main.c
+ $(CC) $(OPT) -c main.c -o main.o $(CFLAGS)
+
+webserver.o: webserver.c
+ $(CC) $(OPT) -c webserver.c -o webserver.o $(CFLAGS)
+
+../common/showmsg.o: ../common/showmsg.c
+ $(CC) $(OPT) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
+
+run:
+ ./webserver
diff --git a/src/webserver/Makefile.win b/src/webserver/Makefile.win
index ed3d57323..65cf676ad 100644
--- a/src/webserver/Makefile.win
+++ b/src/webserver/Makefile.win
@@ -1,35 +1,35 @@
-# Project: Webserver
-# Makefile created by Dev-C++ 4.9.8.0
-
-CPP = g++.exe -D__DEBUG__
-CC = gcc.exe -D__DEBUG__
-WINDRES = windres.exe
-RES =
-OBJ = main.o webserver.o ../common/showmsg.o $(RES)
-LINKOBJ = main.o webserver.o ../common/showmsg.o $(RES)
-LIBS = -L"C:/Program Files/Dev-Cpp/lib" -L"C:/cygwin/lib"
-INCS = -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include" -I"C:/cygwin/usr/include/mingw"
-CXXINCS = -I"C:/Program Files/Dev-Cpp/include/c++" -I"C:/Program Files/Dev-Cpp/include/c++/mingw32" -I"C:/Program Files/Dev-Cpp/include/c++/backward" -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include/c++/3.3.1"
-BIN = webserver.exe
-CXXFLAGS = $(CXXINCS) -pg -g3
-CFLAGS = $(INCS) -pg -g3
-
-.PHONY: all all-before all-after clean clean-custom
-
-all: all-before webserver.exe all-after
-
-
-clean: clean-custom
- rm -f $(OBJ) $(BIN)
-
-$(BIN): $(LINKOBJ)
- $(CC) $(LINKOBJ) -o "webserver.exe" $(LIBS)
-
-main.o: main.c
- $(CC) -c main.c -o main.o $(CFLAGS)
-
-webserver.o: webserver.c
- $(CC) -c webserver.c -o webserver.o $(CFLAGS)
-
-../common/showmsg.o: ../common/showmsg.c
- $(CC) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
+# Project: Webserver
+# Makefile created by Dev-C++ 4.9.8.0
+
+CPP = g++.exe -D__DEBUG__
+CC = gcc.exe -D__DEBUG__
+WINDRES = windres.exe
+RES =
+OBJ = main.o webserver.o ../common/showmsg.o $(RES)
+LINKOBJ = main.o webserver.o ../common/showmsg.o $(RES)
+LIBS = -L"C:/Program Files/Dev-Cpp/lib" -L"C:/cygwin/lib"
+INCS = -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include" -I"C:/cygwin/usr/include/mingw"
+CXXINCS = -I"C:/Program Files/Dev-Cpp/include/c++" -I"C:/Program Files/Dev-Cpp/include/c++/mingw32" -I"C:/Program Files/Dev-Cpp/include/c++/backward" -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include/c++/3.3.1"
+BIN = webserver.exe
+CXXFLAGS = $(CXXINCS) -pg -g3
+CFLAGS = $(INCS) -pg -g3
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before webserver.exe all-after
+
+
+clean: clean-custom
+ rm -f $(OBJ) $(BIN)
+
+$(BIN): $(LINKOBJ)
+ $(CC) $(LINKOBJ) -o "webserver.exe" $(LIBS)
+
+main.o: main.c
+ $(CC) -c main.c -o main.o $(CFLAGS)
+
+webserver.o: webserver.c
+ $(CC) -c webserver.c -o webserver.o $(CFLAGS)
+
+../common/showmsg.o: ../common/showmsg.c
+ $(CC) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
diff --git a/src/webserver/WEBSER~1.layout b/src/webserver/WEBSER~1.layout
index cbc84d563..49854196f 100644
--- a/src/webserver/WEBSER~1.layout
+++ b/src/webserver/WEBSER~1.layout
@@ -1,24 +1,24 @@
-[Editors]
-Focused=-1
-Order=-1,0
-[Editor_0]
-Open=1
-Top=0
-CursorCol=5
-CursorRow=30
-TopLine=1
-LeftChar=1
-[Editor_1]
-Open=1
-Top=0
-CursorCol=1
-CursorRow=35
-TopLine=16
-LeftChar=1
-[Editor_2]
-Open=1
-Top=1
-CursorCol=14
-CursorRow=4
-TopLine=1
-LeftChar=1
+[Editors]
+Focused=-1
+Order=-1,0
+[Editor_0]
+Open=1
+Top=0
+CursorCol=5
+CursorRow=30
+TopLine=1
+LeftChar=1
+[Editor_1]
+Open=1
+Top=0
+CursorCol=1
+CursorRow=35
+TopLine=16
+LeftChar=1
+[Editor_2]
+Open=1
+Top=1
+CursorCol=14
+CursorRow=4
+TopLine=1
+LeftChar=1
diff --git a/src/webserver/Webserver.dev b/src/webserver/Webserver.dev
index 9e100bacb..5bbb3a08c 100644
--- a/src/webserver/Webserver.dev
+++ b/src/webserver/Webserver.dev
@@ -1,97 +1,97 @@
-[Project]
-FileName=Webserver.dev
-Name=Webserver
-UnitCount=5
-Type=1
-Ver=1
-ObjFiles=
-Includes=
-Libs=
-PrivateResource=
-ResourceIncludes=
-MakeIncludes=
-Compiler=
-CppCompiler=
-Linker=
-IsCpp=0
-Icon=
-ExeOutput=
-ObjectOutput=
-OverrideOutput=1
-OverrideOutputName=webserver.exe
-HostApplication=
-Folders=common
-CommandLine=
-IncludeVersionInfo=0
-SupportXPThemes=0
-CompilerSet=1
-CompilerSettings=000000000000000000
-
-[Unit1]
-FileName=main.c
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c main.c -o main.o webserver.o $(CFLAGS)
-
-[VersionInfo]
-Major=0
-Minor=1
-Release=1
-Build=1
-LanguageID=1033
-CharsetID=1252
-CompanyName=
-FileVersion=
-FileDescription=Developed using the Dev-C++ IDE
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=
-AutoIncBuildNr=0
-
-[Unit2]
-FileName=webserver.c
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=1
-BuildCmd=$(CC) -c webserver.c -o webserver.o $(CFLAGS)
-
-[Unit3]
-FileName=webserver.h
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
-[Unit4]
-FileName=..\common\showmsg.c
-CompileCpp=0
-Folder=common
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
-[Unit5]
-FileName=..\common\showmsg.h
-CompileCpp=0
-Folder=common
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
+[Project]
+FileName=Webserver.dev
+Name=Webserver
+UnitCount=5
+Type=1
+Ver=1
+ObjFiles=
+Includes=
+Libs=
+PrivateResource=
+ResourceIncludes=
+MakeIncludes=
+Compiler=
+CppCompiler=
+Linker=
+IsCpp=0
+Icon=
+ExeOutput=
+ObjectOutput=
+OverrideOutput=1
+OverrideOutputName=webserver.exe
+HostApplication=
+Folders=common
+CommandLine=
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=1
+CompilerSettings=000000000000000000
+
+[Unit1]
+FileName=main.c
+CompileCpp=0
+Folder=
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=$(CC) -c main.c -o main.o webserver.o $(CFLAGS)
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=
+AutoIncBuildNr=0
+
+[Unit2]
+FileName=webserver.c
+CompileCpp=0
+Folder=
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=1
+BuildCmd=$(CC) -c webserver.c -o webserver.o $(CFLAGS)
+
+[Unit3]
+FileName=webserver.h
+CompileCpp=0
+Folder=
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=..\common\showmsg.c
+CompileCpp=0
+Folder=common
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=..\common\showmsg.h
+CompileCpp=0
+Folder=common
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/src/webserver/Webserver.layout b/src/webserver/Webserver.layout
index b61094a58..b99312289 100644
--- a/src/webserver/Webserver.layout
+++ b/src/webserver/Webserver.layout
@@ -1,38 +1,38 @@
-[Editors]
-Focused=0
-Order=0,2,1,-1
-[Editor_0]
-Open=1
-Top=1
-CursorCol=55
-CursorRow=128
-TopLine=95
-LeftChar=1
-[Editor_1]
-Open=1
-Top=0
-CursorCol=25
-CursorRow=113
-TopLine=92
-LeftChar=1
-[Editor_2]
-Open=1
-Top=0
-CursorCol=1
-CursorRow=21
-TopLine=1
-LeftChar=1
-[Editor_3]
-Open=0
-Top=0
-CursorCol=20
-CursorRow=2
-TopLine=1
-LeftChar=1
-[Editor_4]
-Open=0
-Top=0
-CursorCol=20
-CursorRow=1
-TopLine=1
-LeftChar=1
+[Editors]
+Focused=0
+Order=0,2,1,-1
+[Editor_0]
+Open=1
+Top=1
+CursorCol=55
+CursorRow=128
+TopLine=95
+LeftChar=1
+[Editor_1]
+Open=1
+Top=0
+CursorCol=25
+CursorRow=113
+TopLine=92
+LeftChar=1
+[Editor_2]
+Open=1
+Top=0
+CursorCol=1
+CursorRow=21
+TopLine=1
+LeftChar=1
+[Editor_3]
+Open=0
+Top=0
+CursorCol=20
+CursorRow=2
+TopLine=1
+LeftChar=1
+[Editor_4]
+Open=0
+Top=0
+CursorCol=20
+CursorRow=1
+TopLine=1
+LeftChar=1
diff --git a/src/webserver/conf/webserver-athena.conf b/src/webserver/conf/webserver-athena.conf
index 003aababa..6f84aa133 100644
--- a/src/webserver/conf/webserver-athena.conf
+++ b/src/webserver/conf/webserver-athena.conf
@@ -1,36 +1,36 @@
-#############################################################
-# ______ __ __ #
-# /\ _ \/\ \__/\ \ #
-# __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
-# /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
-# /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
-# \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
-# \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
-# eAthena Web Server (Second Edition) #
-# by MC Cameri #
-# ------------------------------------------------------- #
-# -Website/Forum- #
-# http://eathena.deltaanime.net/ #
-# -Download URL- #
-# http://eathena.systeminplace.net/ #
-# -IRC Channel- #
-# irc://irc.deltaanime.net/#athena #
-#############################################################
-
-// Display the eAthena Logo at startup?
-show_title: 1
-
-//Web Server Port
-port: 81
-
-//Web Server Password
-password: juan16
-
-//Page Header
-header: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-//Document index
-document_index: index.xhtml
-
-//Send favorite icon if provided?
-favicon: yes
+#############################################################
+# ______ __ __ #
+# /\ _ \/\ \__/\ \ #
+# __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
+# /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
+# /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
+# \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
+# \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
+# eAthena Web Server (Second Edition) #
+# by MC Cameri #
+# ------------------------------------------------------- #
+# -Website/Forum- #
+# http://eathena.deltaanime.net/ #
+# -Download URL- #
+# http://eathena.systeminplace.net/ #
+# -IRC Channel- #
+# irc://irc.deltaanime.net/#athena #
+#############################################################
+
+// Display the eAthena Logo at startup?
+show_title: 1
+
+//Web Server Port
+port: 81
+
+//Web Server Password
+password: juan16
+
+//Page Header
+header: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+//Document index
+document_index: index.xhtml
+
+//Send favorite icon if provided?
+favicon: yes
diff --git a/src/webserver/main.c b/src/webserver/main.c
index 941a7a348..915d71b6d 100644
--- a/src/webserver/main.c
+++ b/src/webserver/main.c
@@ -1,144 +1,144 @@
-/******************************************************************************
- # ______ __ __ #
- # /\ _ \/\ \__/\ \ #
- # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
- # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
- # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
- # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
- # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
- # eAthena Web Server (Second Edition) #
- # by MC Cameri #
- # ------------------------------------------------------- #
- # -Website/Forum- #
- # http://eathena.deltaanime.net/ #
- # -Download URL- #
- # http://eathena.systeminplace.net/ #
- # -IRC Channel- #
- # irc://irc.deltaanime.net/#athena #
- ******************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "../common/showmsg.h"
-#include "webserver.h"
-
-char ws_password[17];
-char ws_header[128];
-
-#define WEB_CONF "conf/webserver-athena.conf"
-#define MAX_CONNECTIONS 10
-#define HOME "home/"
-
-struct config config;
-
-int main(int argc, char *argv[])
-{
- int server_fd, client_fd;
- int sin_size;
- struct sockaddr_in server_addr;
- struct sockaddr_in client_addr;
- struct sigaction sa;
- char recvin[1024];
- char path[1024];
- char line[1024];
- int optval = 1;
- if (ws_config_read(WEB_CONF)) exit(0);
- if (config.show_title)
- ws_display_title();
- else
- printf("eAthena Web Server (Second Edition)\n");
- if (strcmpEx(ws_password,"webpass")==0)
- ShowWarning("You are using the default password (webpass), we highly "
- "recommend\n that you change it.\n");
- else if (strstr(ws_password,"webpass"))
- ShowWarning("Your password should not contain \"webpass\" in it, it is"
- " highly\n recommended that you change it.\n");
- printf("Web Server Password: %s\n",ws_password);
- printf("Web Server Port: %d\n",config.port);
-
- if ((server_fd = socket(AF_INET, SOCK_STREAM,0)) == -1) {
- ShowError("In main() -> Could not open socket.\n");
- return 1;
- }
- if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1) {
- ShowError("In main() -> Could not set socket options.\n");
- return 1;
- }
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(config.port);
- server_addr.sin_addr.s_addr = INADDR_ANY;
- memset(&(server_addr.sin_zero), '\0', 8);
-
- if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {
- snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not bind to port number: %d\n",config.port);
- ShowError(tmp_output);
- return 1;
- }
-
- if (listen(server_fd, MAX_CONNECTIONS) < 0) {
- snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not listen on port number: %d\n",config.port);
- ShowError(tmp_output);
- return 1;
- }
-
- sa.sa_handler = ws_sigchld_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
-
- if (sigaction(SIGCHLD, &sa, NULL) < 0) {
- ShowError("In main() -> Invalid sigaction.\n");
- return 1;
- }
- ShowInfo("eAthena Web Server is now listening for incoming connections.\n");
-
- while(1)
- {
- sin_size = sizeof(struct sockaddr_in);
- client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size);
-
- if (!fork())
- {
- close(server_fd);
- memset(recvin, 0x0, 500);
- recv(client_fd, recvin, 500, 0);
- char *html_output;
- int count = 0;
- if (sscanf(recvin,"GET %[a-zA-Z_-.+\%#@~] %*[^\n]",path)==1) {
- FILE *fp;
- strcpy(tmp_output,HOME);
- strcat(tmp_output,path);
- fp = fopen(tmp_output,"r+");
- if (fp==NULL) {
- send(client_fd,"File not found",strlen("File not found"), 0);
- close(client_fd);
- }
- memset(tmp_output,0x0,strlen(tmp_output));
- html_output = (char*)malloc(sizeof(char)*2);
- while (fgets(line,1023,fp)) {
- html_output = (char*)realloc(sizeof(html_output)+(sizeof(char)*count));
- strcat(html_output,line);
- printf(line);
- }
- send(client_fd,tmp_output,sizeof(tmp_output),0);
- fclose(fp);
- }
- // send(client_fd, ws_header, strlen(ws_header), 0);
- // generate_page(password, client_fd, get_query(recvin), inet_ntoa(client_addr.sin_addr));
- // log_visit(get_query(recvin), inet_ntoa(client_addr.sin_addr));
- close(client_fd);
- exit(0);
- }
- close(client_fd);
- }
- return 0;
-}
+/******************************************************************************
+ # ______ __ __ #
+ # /\ _ \/\ \__/\ \ #
+ # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
+ # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
+ # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
+ # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
+ # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
+ # eAthena Web Server (Second Edition) #
+ # by MC Cameri #
+ # ------------------------------------------------------- #
+ # -Website/Forum- #
+ # http://eathena.deltaanime.net/ #
+ # -Download URL- #
+ # http://eathena.systeminplace.net/ #
+ # -IRC Channel- #
+ # irc://irc.deltaanime.net/#athena #
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../common/showmsg.h"
+#include "webserver.h"
+
+char ws_password[17];
+char ws_header[128];
+
+#define WEB_CONF "conf/webserver-athena.conf"
+#define MAX_CONNECTIONS 10
+#define HOME "home/"
+
+struct config config;
+
+int main(int argc, char *argv[])
+{
+ int server_fd, client_fd;
+ int sin_size;
+ struct sockaddr_in server_addr;
+ struct sockaddr_in client_addr;
+ struct sigaction sa;
+ char recvin[1024];
+ char path[1024];
+ char line[1024];
+ int optval = 1;
+ if (ws_config_read(WEB_CONF)) exit(0);
+ if (config.show_title)
+ ws_display_title();
+ else
+ printf("eAthena Web Server (Second Edition)\n");
+ if (strcmpEx(ws_password,"webpass")==0)
+ ShowWarning("You are using the default password (webpass), we highly "
+ "recommend\n that you change it.\n");
+ else if (strstr(ws_password,"webpass"))
+ ShowWarning("Your password should not contain \"webpass\" in it, it is"
+ " highly\n recommended that you change it.\n");
+ printf("Web Server Password: %s\n",ws_password);
+ printf("Web Server Port: %d\n",config.port);
+
+ if ((server_fd = socket(AF_INET, SOCK_STREAM,0)) == -1) {
+ ShowError("In main() -> Could not open socket.\n");
+ return 1;
+ }
+ if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1) {
+ ShowError("In main() -> Could not set socket options.\n");
+ return 1;
+ }
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = htons(config.port);
+ server_addr.sin_addr.s_addr = INADDR_ANY;
+ memset(&(server_addr.sin_zero), '\0', 8);
+
+ if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {
+ snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not bind to port number: %d\n",config.port);
+ ShowError(tmp_output);
+ return 1;
+ }
+
+ if (listen(server_fd, MAX_CONNECTIONS) < 0) {
+ snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not listen on port number: %d\n",config.port);
+ ShowError(tmp_output);
+ return 1;
+ }
+
+ sa.sa_handler = ws_sigchld_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+
+ if (sigaction(SIGCHLD, &sa, NULL) < 0) {
+ ShowError("In main() -> Invalid sigaction.\n");
+ return 1;
+ }
+ ShowInfo("eAthena Web Server is now listening for incoming connections.\n");
+
+ while(1)
+ {
+ sin_size = sizeof(struct sockaddr_in);
+ client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size);
+
+ if (!fork())
+ {
+ close(server_fd);
+ memset(recvin, 0x0, 500);
+ recv(client_fd, recvin, 500, 0);
+ char *html_output;
+ int count = 0;
+ if (sscanf(recvin,"GET %[a-zA-Z_-.+\%#@~] %*[^\n]",path)==1) {
+ FILE *fp;
+ strcpy(tmp_output,HOME);
+ strcat(tmp_output,path);
+ fp = fopen(tmp_output,"r+");
+ if (fp==NULL) {
+ send(client_fd,"File not found",strlen("File not found"), 0);
+ close(client_fd);
+ }
+ memset(tmp_output,0x0,strlen(tmp_output));
+ html_output = (char*)malloc(sizeof(char)*2);
+ while (fgets(line,1023,fp)) {
+ html_output = (char*)realloc(sizeof(html_output)+(sizeof(char)*count));
+ strcat(html_output,line);
+ printf(line);
+ }
+ send(client_fd,tmp_output,sizeof(tmp_output),0);
+ fclose(fp);
+ }
+ // send(client_fd, ws_header, strlen(ws_header), 0);
+ // generate_page(password, client_fd, get_query(recvin), inet_ntoa(client_addr.sin_addr));
+ // log_visit(get_query(recvin), inet_ntoa(client_addr.sin_addr));
+ close(client_fd);
+ exit(0);
+ }
+ close(client_fd);
+ }
+ return 0;
+}
diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c
index 3a2b9b2dd..0169cd028 100644
--- a/src/webserver/webserver.c
+++ b/src/webserver/webserver.c
@@ -1,136 +1,136 @@
-/******************************************************************************
- # ______ __ __ #
- # /\ _ \/\ \__/\ \ #
- # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
- # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
- # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
- # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
- # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
- # eAthena Web Server (Second Edition) #
- # by MC Cameri #
- # ------------------------------------------------------- #
- # -Website/Forum- #
- # http://eathena.deltaanime.net/ #
- # -Download URL- #
- # http://eathena.systeminplace.net/ #
- # -IRC Channel- #
- # irc://irc.deltaanime.net/#athena #
- ******************************************************************************/
-
-#include <stdio.h>
-#include <strings.h>
-#include "../common/showmsg.h"
-#include "webserver.h"
-
-char ws_password[17] = "pass";
-char ws_header[128] = {'\0'};
-
-/* Displays the eAthena Logo */
-void ws_display_title(void)
-{
- printf("\033[2J");
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m _ _ _ _ _ _ _ _ _ _ _ _ _ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[0;44m (\033[1;33m Advanced Fusion Maps (c) 2003-2004 The Fusion Project \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
-}
-/* Returns a boolean value given character string */
-int ws_config_switch(const char *str) {
- if (strcmpEx(str, "on") == 0 || strcmpEx(str, "yes") == 0 ||
- strcmpEx(str, "oui") == 0 || strcmpEx(str, "ja") == 0 ||
- strcmpEx(str, "si") == 0 || strcmpEx(str,"true") == 0)
- return 1;
- if (strcmpEx(str, "off") == 0 || strcmpEx(str, "no") == 0 ||
- strcmpEx(str, "non") == 0 || strcmpEx(str, "nein") == 0 ||
- strcmpEx(str, "false") == 0)
- return 0;
- return atoi(str);
-}
-
-/* Reads the eAthena Web Server's configuration file */
-int ws_config_read(const char *cfgName)
-{
- int i;
- char line[1024],w1[1024],w2[1024],temp[1024];
- FILE *fp;
-
- /* Default values */
- config.show_title=0;
- config.port=80;
-
-
- fp=fopen(cfgName,"r");
- if(fp==NULL){
- snprintf(temp,sizeof(temp),"Could not open \033[1;29m%s\033[0;0m, file not found.\n",cfgName);
- ShowMessage(temp,MSG_ERROR);
- return 1;
- }
- while(fgets(line,1020,fp)){
- const struct {
- char str[128];
- int *val;
- } data[] ={
- //List of variables
- { "show_title", &config.show_title },
- { "port", &config.port },
- };
-
- if((line[0] == '/' && line[1] == '/') || (line[0]=='#') ||
- (sscanf(line,"%1023[^:]:%1023[^\n]",w1,w2) !=2))
- continue;
- for(i=0;i<sizeof(data)/(sizeof(data[0]));i++) {
- if(strcmpEx(w1,data[i].str)==0){
- *data[i].val=ws_config_switch(w2);
- break;
- }
- }
- if(strcmpEx(w1,"import")==0) {
- ws_config_read(w2);
- continue;
- }
- if(strcmpEx(w1,"password")==0) {
- if (strlen(w2)>16) {
- ShowError("The Web Server password is too long, maximum passwor"
- "d length is 16 characters.\n");
- return 1;
- }
- strcpy(ws_password,w2);
- continue;
- }
- if(strcmpEx(w1,"header")==0) {
- if (strlen(w2)>127) {
- ShowError("The Web Server header is too long, maximum header"
- "d length is 127 characters.\n");
- return 1;
- }
- strcpy(ws_header,w2);
- continue;
- }
- }
- fclose(fp);
-
- //Correct values
- if(config.show_title < 0)
- config.show_title = 0;
- if(config.port < 1 || config.port > 65534)
- config.port=80;
-
- return 0;
-}
-
-void ws_sigchld_handler(int s)
-{
- while(wait(NULL) > 0);
-}
+/******************************************************************************
+ # ______ __ __ #
+ # /\ _ \/\ \__/\ \ #
+ # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
+ # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
+ # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
+ # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
+ # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
+ # eAthena Web Server (Second Edition) #
+ # by MC Cameri #
+ # ------------------------------------------------------- #
+ # -Website/Forum- #
+ # http://eathena.deltaanime.net/ #
+ # -Download URL- #
+ # http://eathena.systeminplace.net/ #
+ # -IRC Channel- #
+ # irc://irc.deltaanime.net/#athena #
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <strings.h>
+#include "../common/showmsg.h"
+#include "webserver.h"
+
+char ws_password[17] = "pass";
+char ws_header[128] = {'\0'};
+
+/* Displays the eAthena Logo */
+void ws_display_title(void)
+{
+ printf("\033[2J");
+ printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ \033[0;44m)\033[K\033[0m\n");
+ printf("\033[0;44m (\033[1m _ _ _ _ _ _ _ _ _ _ _ _ _ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
+ printf("\033[0;44m (\033[1;33m Advanced Fusion Maps (c) 2003-2004 The Fusion Project \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
+ printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
+}
+/* Returns a boolean value given character string */
+int ws_config_switch(const char *str) {
+ if (strcmpEx(str, "on") == 0 || strcmpEx(str, "yes") == 0 ||
+ strcmpEx(str, "oui") == 0 || strcmpEx(str, "ja") == 0 ||
+ strcmpEx(str, "si") == 0 || strcmpEx(str,"true") == 0)
+ return 1;
+ if (strcmpEx(str, "off") == 0 || strcmpEx(str, "no") == 0 ||
+ strcmpEx(str, "non") == 0 || strcmpEx(str, "nein") == 0 ||
+ strcmpEx(str, "false") == 0)
+ return 0;
+ return atoi(str);
+}
+
+/* Reads the eAthena Web Server's configuration file */
+int ws_config_read(const char *cfgName)
+{
+ int i;
+ char line[1024],w1[1024],w2[1024],temp[1024];
+ FILE *fp;
+
+ /* Default values */
+ config.show_title=0;
+ config.port=80;
+
+
+ fp=fopen(cfgName,"r");
+ if(fp==NULL){
+ snprintf(temp,sizeof(temp),"Could not open \033[1;29m%s\033[0;0m, file not found.\n",cfgName);
+ ShowMessage(temp,MSG_ERROR);
+ return 1;
+ }
+ while(fgets(line,1020,fp)){
+ const struct {
+ char str[128];
+ int *val;
+ } data[] ={
+ //List of variables
+ { "show_title", &config.show_title },
+ { "port", &config.port },
+ };
+
+ if((line[0] == '/' && line[1] == '/') || (line[0]=='#') ||
+ (sscanf(line,"%1023[^:]:%1023[^\n]",w1,w2) !=2))
+ continue;
+ for(i=0;i<sizeof(data)/(sizeof(data[0]));i++) {
+ if(strcmpEx(w1,data[i].str)==0){
+ *data[i].val=ws_config_switch(w2);
+ break;
+ }
+ }
+ if(strcmpEx(w1,"import")==0) {
+ ws_config_read(w2);
+ continue;
+ }
+ if(strcmpEx(w1,"password")==0) {
+ if (strlen(w2)>16) {
+ ShowError("The Web Server password is too long, maximum passwor"
+ "d length is 16 characters.\n");
+ return 1;
+ }
+ strcpy(ws_password,w2);
+ continue;
+ }
+ if(strcmpEx(w1,"header")==0) {
+ if (strlen(w2)>127) {
+ ShowError("The Web Server header is too long, maximum header"
+ "d length is 127 characters.\n");
+ return 1;
+ }
+ strcpy(ws_header,w2);
+ continue;
+ }
+ }
+ fclose(fp);
+
+ //Correct values
+ if(config.show_title < 0)
+ config.show_title = 0;
+ if(config.port < 1 || config.port > 65534)
+ config.port=80;
+
+ return 0;
+}
+
+void ws_sigchld_handler(int s)
+{
+ while(wait(NULL) > 0);
+}
diff --git a/src/webserver/webserver.h b/src/webserver/webserver.h
index 8bb84b875..84ef02b62 100644
--- a/src/webserver/webserver.h
+++ b/src/webserver/webserver.h
@@ -1,21 +1,21 @@
-#ifndef WEBSERV_H_
-#define WEBSERV_H_
-
-#define strcmpEx(x,y) (strcasecmp(x,y))
-
-extern void ws_display_title(void);
-
-extern int ws_config_read(const char *cfgName);
-
-extern struct config {
- int show_title;
- int port;
-} config;
-
-extern char ws_password[17]; //16 chars + \0
-
-extern char ws_header[128]; //!?
-
-extern void ws_sigchld_handler(int s);
-
-#endif
+#ifndef WEBSERV_H_
+#define WEBSERV_H_
+
+#define strcmpEx(x,y) (strcasecmp(x,y))
+
+extern void ws_display_title(void);
+
+extern int ws_config_read(const char *cfgName);
+
+extern struct config {
+ int show_title;
+ int port;
+} config;
+
+extern char ws_password[17]; //16 chars + \0
+
+extern char ws_header[128]; //!?
+
+extern void ws_sigchld_handler(int s);
+
+#endif