rathena/src/login_sql/char_int.c
amber 717714e5b8 props
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@508 54d463be-8e91-2dee-dedb-b68131a5f0ec
2004-12-08 06:02:53 +00:00

492 lines
14 KiB
C

#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;
}