📄 char.c
字号:
// $Id: char2.c,v 1.4 2003/06/29 05:50:51 lemit Exp $
// original : char2.c 2003/03/14 11:58:35 Rev.1.5
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "core.h"
#include "socket.h"
#include "timer.h"
#include "mmo.h"
#include "version.h"
#include "lock.h"
#include "char.h"
#include "inter.h"
#include "int_pet.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
struct mmo_map_server server[MAX_MAP_SERVERS];
int server_fd[MAX_MAP_SERVERS];
int login_fd;
char userid[24];
char passwd[24];
char server_name[20];
char login_ip_str[16];
int login_ip;
int login_port = 6900;
char char_ip_str[16];
int char_ip;
int char_port = 6121;
int char_maintenance;
int char_new;
char char_txt[1024];
char unknown_char_name[1024]="Unknown";
char char_log_filename[1024]="log/char.log";
#define CHAR_STATE_WAITAUTH 0
#define CHAR_STATE_AUTHOK 1
struct char_session_data{
int state;
int account_id,login_id1,login_id2,sex;
int found_char[9];
};
#define AUTH_FIFO_SIZE 256
struct {
int account_id,char_id,login_id1,char_pos,delflag,sex;
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos=0;
int char_id_count=150000;
struct mmo_charstatus *char_dat;
int char_num,char_max;
int max_connect_user=0;
int autosave_interval=DEFAULT_AUTOSAVE_INTERVAL;
int start_zeny = 500;
// 弶婜埵抲乮conf僼傽僀儖偐傜嵞愝掕壜擻乯
struct point start_point={"new_1-1.gat",53,111};
int mmo_char_tostr(char *str,struct mmo_charstatus *p)
{
int i;
char *str_p = str;
str_p += sprintf(str_p,"%d\t%d,%d\t%s\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
"\t%s,%d,%d\t%s,%d,%d\t",
p->char_id,p->account_id,p->char_num,p->name, //
p->class,p->base_level,p->job_level,
p->base_exp,p->job_exp,p->zeny,
p->hp,p->max_hp,p->sp,p->max_sp,
p->str,p->agi,p->vit,p->int_,p->dex,p->luk,
p->status_point,p->skill_point,
p->option,p->karma,p->manner, //
p->party_id,p->guild_id,p->pet_id,
p->hair,p->hair_color,p->clothes_color,
p->weapon,p->shield,p->head_top,p->head_mid,p->head_bottom,
p->last_point.map,p->last_point.x,p->last_point.y, //
p->save_point.map,p->save_point.x,p->save_point.y
);
for(i=0;i<10;i++)
if(p->memo_point[i].map[0]){
str_p += sprintf(str_p,"%s,%d,%d",p->memo_point[i].map,p->memo_point[i].x,p->memo_point[i].y);
}
*(str_p++)='\t';
for(i=0;i<MAX_INVENTORY;i++)
if(p->inventory[i].nameid){
str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
p->inventory[i].id,p->inventory[i].nameid,p->inventory[i].amount,p->inventory[i].equip,
p->inventory[i].identify,p->inventory[i].refine,p->inventory[i].attribute,
p->inventory[i].card[0],p->inventory[i].card[1],p->inventory[i].card[2],p->inventory[i].card[3]);
}
*(str_p++)='\t';
for(i=0;i<MAX_CART;i++)
if(p->cart[i].nameid){
str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
p->cart[i].id,p->cart[i].nameid,p->cart[i].amount,p->cart[i].equip,
p->cart[i].identify,p->cart[i].refine,p->cart[i].attribute,
p->cart[i].card[0],p->cart[i].card[1],p->cart[i].card[2],p->cart[i].card[3]);
}
*(str_p++)='\t';
for(i=0;i<MAX_SKILL;i++)
if(p->skill[i].id && p->skill[i].flag!=1){
str_p += sprintf(str_p,"%d,%d ",p->skill[i].id,(p->skill[i].flag==0)?p->skill[i].lv:p->skill[i].flag-2);
}
*(str_p++)='\t';
for(i=0;i<p->global_reg_num;i++)
str_p += sprintf(str_p,"%s,%d ",p->global_reg[i].str,p->global_reg[i].value);
*(str_p++)='\t';
*str_p='\0';
return 0;
}
/*
int mmo_char_tostr(char *str,struct mmo_charstatus *p)
{
int i;
sprintf(str,"%d\t%d,%d\t%s\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
"\t%s,%d,%d\t%s,%d,%d",
p->char_id,p->account_id,p->char_num,p->name, //
p->class,p->base_level,p->job_level,
p->base_exp,p->job_exp,p->zeny,
p->hp,p->max_hp,p->sp,p->max_sp,
p->str,p->agi,p->vit,p->int_,p->dex,p->luk,
p->status_point,p->skill_point,
p->option,p->karma,p->manner, //
p->party_id,p->guild_id,p->pet_id,
p->hair,p->hair_color,p->clothes_color,
p->weapon,p->shield,p->head_top,p->head_mid,p->head_bottom,
p->last_point.map,p->last_point.x,p->last_point.y, //
p->save_point.map,p->save_point.x,p->save_point.y
);
strcat(str,"\t");
for(i=0;i<10;i++)
if(p->memo_point[i].map[0]){
sprintf(str+strlen(str),"%s,%d,%d",p->memo_point[i].map,p->memo_point[i].x,p->memo_point[i].y);
}
strcat(str,"\t");
for(i=0;i<MAX_INVENTORY;i++)
if(p->inventory[i].nameid){
sprintf(str+strlen(str),"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
p->inventory[i].id,p->inventory[i].nameid,p->inventory[i].amount,p->inventory[i].equip,
p->inventory[i].identify,p->inventory[i].refine,p->inventory[i].attribute,
p->inventory[i].card[0],p->inventory[i].card[1],p->inventory[i].card[2],p->inventory[i].card[3]);
}
strcat(str,"\t");
for(i=0;i<MAX_CART;i++)
if(p->cart[i].nameid){
sprintf(str+strlen(str),"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
p->cart[i].id,p->cart[i].nameid,p->cart[i].amount,p->cart[i].equip,
p->cart[i].identify,p->cart[i].refine,p->cart[i].attribute,
p->cart[i].card[0],p->cart[i].card[1],p->cart[i].card[2],p->cart[i].card[3]);
}
strcat(str,"\t");
for(i=0;i<MAX_SKILL;i++)
if(p->skill[i].id && p->skill[i].flag!=1){
sprintf(str+strlen(str),"%d,%d ",p->skill[i].id,(p->skill[i].flag==0)?p->skill[i].lv:p->skill[i].flag-2);
}
strcat(str,"\t");
for(i=0;i<p->global_reg_num;i++)
sprintf(str+strlen(str),"%s,%d ",p->global_reg[i].str,p->global_reg[i].value);
strcat(str,"\t");
return 0;
}
*/
int mmo_char_fromstr(char *str,struct mmo_charstatus *p)
{
int tmp_int[256];
int set,next,len,i;
// 384埲崀偺宍幃撉傒崬傒
if( (set=sscanf(str,"%d\t%d,%d\t%[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
"\t%[^,],%d,%d\t%[^,],%d,%d%n",
&tmp_int[0],&tmp_int[1],&tmp_int[2],p->name, //
&tmp_int[3],&tmp_int[4],&tmp_int[5],
&tmp_int[6],&tmp_int[7],&tmp_int[8],
&tmp_int[9],&tmp_int[10],&tmp_int[11],&tmp_int[12],
&tmp_int[13],&tmp_int[14],&tmp_int[15],&tmp_int[16],&tmp_int[17],&tmp_int[18],
&tmp_int[19],&tmp_int[20],
&tmp_int[21],&tmp_int[22],&tmp_int[23], //
&tmp_int[24],&tmp_int[25],&tmp_int[26],
&tmp_int[27],&tmp_int[28],&tmp_int[29],
&tmp_int[30],&tmp_int[31],&tmp_int[32],&tmp_int[33],&tmp_int[34],
p->last_point.map,&tmp_int[35],&tmp_int[36], //
p->save_point.map,&tmp_int[37],&tmp_int[38],&next
)
)!=42 ){
// 384埲慜偺宍幃偺撉傒崬傒
tmp_int[26]=0;
set=sscanf(str,"%d\t%d,%d\t%[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
"\t%[^,],%d,%d\t%[^,],%d,%d%n",
&tmp_int[0],&tmp_int[1],&tmp_int[2],p->name, //
&tmp_int[3],&tmp_int[4],&tmp_int[5],
&tmp_int[6],&tmp_int[7],&tmp_int[8],
&tmp_int[9],&tmp_int[10],&tmp_int[11],&tmp_int[12],
&tmp_int[13],&tmp_int[14],&tmp_int[15],&tmp_int[16],&tmp_int[17],&tmp_int[18],
&tmp_int[19],&tmp_int[20],
&tmp_int[21],&tmp_int[22],&tmp_int[23], //
&tmp_int[24],&tmp_int[25],//
&tmp_int[27],&tmp_int[28],&tmp_int[29],
&tmp_int[30],&tmp_int[31],&tmp_int[32],&tmp_int[33],&tmp_int[34],
p->last_point.map,&tmp_int[35],&tmp_int[36], //
p->save_point.map,&tmp_int[37],&tmp_int[38],&next);
set++;
}
p->char_id=tmp_int[0];
p->account_id=tmp_int[1];
p->char_num=tmp_int[2];
p->class=tmp_int[3];
p->base_level=tmp_int[4];
p->job_level=tmp_int[5];
p->base_exp=tmp_int[6];
p->job_exp=tmp_int[7];
p->zeny=tmp_int[8];
p->hp=tmp_int[9];
p->max_hp=tmp_int[10];
p->sp=tmp_int[11];
p->max_sp=tmp_int[12];
p->str=tmp_int[13];
p->agi=tmp_int[14];
p->vit=tmp_int[15];
p->int_=tmp_int[16];
p->dex=tmp_int[17];
p->luk=tmp_int[18];
p->status_point=tmp_int[19];
p->skill_point=tmp_int[20];
p->option=tmp_int[21];
p->karma=tmp_int[22];
p->manner=tmp_int[23];
p->party_id=tmp_int[24];
p->guild_id=tmp_int[25];
p->pet_id=tmp_int[26];
p->hair=tmp_int[27];
p->hair_color=tmp_int[28];
p->clothes_color=tmp_int[29];
p->weapon=tmp_int[30];
p->shield=tmp_int[31];
p->head_top=tmp_int[32];
p->head_mid=tmp_int[33];
p->head_bottom=tmp_int[34];
p->last_point.x=tmp_int[35];
p->last_point.y=tmp_int[36];
p->save_point.x=tmp_int[37];
p->save_point.y=tmp_int[38];
if(set!=42)
return 0;
if(str[next]=='\n' || str[next]=='\r')
return 1; // 怴婯僨乕僞
next++;
for(i=0;str[next] && str[next]!='\t';i++){
set=sscanf(str+next,"%[^,],%d,%d%n",p->memo_point[i].map,&tmp_int[0],&tmp_int[1],&len);
if(set!=3)
return 0;
p->memo_point[i].x=tmp_int[0];
p->memo_point[i].y=tmp_int[1];
next+=len;
if(str[next]==' ')
next++;
}
next++;
for(i=0;str[next] && str[next]!='\t';i++){
set=sscanf(str+next,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0],&tmp_int[1],&tmp_int[2],&tmp_int[3],
&tmp_int[4],&tmp_int[5],&tmp_int[6],
&tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10],&len);
if(set!=11)
return 0;
p->inventory[i].id=tmp_int[0];
p->inventory[i].nameid=tmp_int[1];
p->inventory[i].amount=tmp_int[2];
p->inventory[i].equip=tmp_int[3];
p->inventory[i].identify=tmp_int[4];
p->inventory[i].refine=tmp_int[5];
p->inventory[i].attribute=tmp_int[6];
p->inventory[i].card[0]=tmp_int[7];
p->inventory[i].card[1]=tmp_int[8];
p->inventory[i].card[2]=tmp_int[9];
p->inventory[i].card[3]=tmp_int[10];
next+=len;
if(str[next]==' ')
next++;
}
next++;
for(i=0;str[next] && str[next]!='\t';i++){
set=sscanf(str+next,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0],&tmp_int[1],&tmp_int[2],&tmp_int[3],
&tmp_int[4],&tmp_int[5],&tmp_int[6],
&tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10],&len);
if(set!=11)
return 0;
p->cart[i].id=tmp_int[0];
p->cart[i].nameid=tmp_int[1];
p->cart[i].amount=tmp_int[2];
p->cart[i].equip=tmp_int[3];
p->cart[i].identify=tmp_int[4];
p->cart[i].refine=tmp_int[5];
p->cart[i].attribute=tmp_int[6];
p->cart[i].card[0]=tmp_int[7];
p->cart[i].card[1]=tmp_int[8];
p->cart[i].card[2]=tmp_int[9];
p->cart[i].card[3]=tmp_int[10];
next+=len;
if(str[next]==' ')
next++;
}
next++;
for(i=0;str[next] && str[next]!='\t';i++){
set=sscanf(str+next,"%d,%d%n",
&tmp_int[0],&tmp_int[1],&len);
if(set!=2)
return 0;
p->skill[tmp_int[0]].id=tmp_int[0];
p->skill[tmp_int[0]].lv=tmp_int[1];
next+=len;
if(str[next]==' ')
next++;
}
next++;
for(i=0;str[next] && str[next]!='\t' && str[next]!='\n' && str[next]!='\r';i++){ //global_reg幚憰埲慜偺athena.txt屳姺偺偨傔堦墳'\n'僠僃僢僋
set=sscanf(str+next,"%[^,],%d%n",
p->global_reg[i].str,&p->global_reg[i].value,&len);
if(set!=2)
return 0;
next+=len;
if(str[next]==' ')
next++;
}
p->global_reg_num=i;
return 1;
}
int mmo_char_init(void)
{
char line[65536];
int ret;
FILE *fp;
fp=fopen(char_txt,"r");
char_dat=calloc(sizeof(char_dat[0])*256, 1);
if (!char_dat) {
printf("out of memory: mmo_char_init\n");
exit(1);
}
char_max=256;
if(fp==NULL)
return 0;
while(fgets(line,65535,fp)){
if(char_num>=char_max){
char_max+=256;
char_dat=realloc(char_dat,sizeof(char_dat[0])*char_max);
if (!char_dat) {
printf("out of memory: mmo_char_init\n");
exit(1);
}
memset(char_dat + (char_max - 256), '\0',
256 * sizeof(*char_dat));
}
memset(&char_dat[char_num],0,sizeof(char_dat[0]));
ret=mmo_char_fromstr(line,&char_dat[char_num]);
if(ret){
if(char_dat[char_num].char_id>=char_id_count)
char_id_count=char_dat[char_num].char_id+1;
char_num++;
}
}
fclose(fp);
return 0;
}
void mmo_char_sync(void)
{
char line[65536];
int i,lock;
FILE *fp;
fp=lock_fopen(char_txt,&lock);
if(fp==NULL)
return;
for(i=0;i<char_num;i++){
mmo_char_tostr(line,&char_dat[i]);
fprintf(fp,"%s" RETCODE,line);
}
lock_fclose(fp,char_txt,&lock);
}
int mmo_char_sync_timer(int tid,unsigned int tick,int id,int data)
{
mmo_char_sync();
inter_save();
return 0;
}
int make_new_char(int fd,unsigned char *dat)
{
int i;
struct char_session_data *sd;
FILE *logfp;
for(i=0;i<24 && dat[i];i++){
if(dat[i]<0x20 || dat[i]==0x7f)
return -1;
}
if(dat[24]+dat[25]+dat[26]+dat[27]+dat[28]+dat[29]>5*6 ||
dat[30]>=9 ||
dat[33]==0 || dat[33]>=20 ||
dat[31]>=9){
logfp=fopen(char_log_filename,"a");
if(logfp){
fprintf(logfp,"make new char error %d-%d %s %d,%d,%d,%d,%d,%d %d,%d" RETCODE,
fd,dat[30],dat,dat[24],dat[25],dat[26],dat[27],dat[28],dat[29],dat[33],dat[31]);
fclose(logfp);
}
return -1;
}
logfp=fopen(char_log_filename,"a");
if(logfp){
fprintf(logfp,"make new char %d-%d %s" RETCODE,fd,dat[30],dat);
fclose(logfp);
}
sd=session[fd]->session_data;
for(i=0;i<char_num;i++){
if(strcmp(char_dat[i].name,dat)==0 || (char_dat[i].account_id==sd->account_id && char_dat[i].char_num==dat[30]))
break;
}
if(i!=char_num)
return -1;
if(char_num>=char_max){
char_max+=256;
char_dat=realloc(char_dat,sizeof(char_dat[0])*char_max);
if (!char_dat) {
printf("out of memory: make_new_char\n");
exit(1);
}
memset(char_dat + (char_max - 256), '\0', 256 * sizeof(*char_dat));
}
memset(&char_dat[i],0,sizeof(char_dat[0]));
char_dat[i].char_id=char_id_count++;
char_dat[i].account_id=sd->account_id;
char_dat[i].char_num=dat[30];
strcpy(char_dat[i].name,dat);
char_dat[i].class=0;
char_dat[i].base_level=1;
char_dat[i].job_level=1;
char_dat[i].base_exp=0;
char_dat[i].job_exp=0;
char_dat[i].zeny=start_zeny;
char_dat[i].str=dat[24];
char_dat[i].agi=dat[25];
char_dat[i].vit=dat[26];
char_dat[i].int_=dat[27];
char_dat[i].dex=dat[28];
char_dat[i].luk=dat[29];
char_dat[i].max_hp=40 * (100 + char_dat[i].vit)/100;
char_dat[i].max_sp=11 * (100 + char_dat[i].int_)/100;;
char_dat[i].hp=char_dat[i].max_hp;
char_dat[i].sp=char_dat[i].max_sp;
char_dat[i].status_point=0;
char_dat[i].skill_point=0;
char_dat[i].option=0;
char_dat[i].karma=0;
char_dat[i].manner=0;
char_dat[i].party_id=0;
char_dat[i].guild_id=0;
char_dat[i].hair=dat[33];
char_dat[i].hair_color=dat[31];
char_dat[i].clothes_color=0;
char_dat[i].inventory[0].nameid = 1201; /* Knife */
char_dat[i].inventory[0].amount = 1;
char_dat[i].inventory[0].equip = 0x02;
char_dat[i].inventory[0].identify = 1;
char_dat[i].inventory[1].nameid = 2301; /* Cotton Shirt */
char_dat[i].inventory[1].amount = 1;
char_dat[i].inventory[1].equip = 0x10;
char_dat[i].inventory[1].identify = 1;
char_dat[i].weapon = 1;
char_dat[i].shield=0;
char_dat[i].head_top=0;
char_dat[i].head_mid=0;
char_dat[i].head_bottom=0;
memcpy(&char_dat[i].last_point,&start_point,sizeof(start_point));
memcpy(&char_dat[i].save_point,&start_point,sizeof(start_point));
/*strcpy(char_dat[i].last_point.map,"new_1-1.gat");
char_dat[i].last_point.x=start_po;
char_dat[i].last_point.y=111;
strcpy(char_dat[i].save_point.map,"new_1-1.gat");
char_dat[i].save_point.x=53;
char_dat[i].save_point.y=111;*/
char_num++;
mmo_char_sync();
return i;
}
int count_users(void)
{
if(login_fd>0 && session[login_fd]){
int i,users;
for(i=0,users=0;i<MAX_MAP_SERVERS;i++){
if(server_fd[i]>0){
users+=server[i].users;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -