Ejemplo n.º 1
0
static int on_client_createcharreq(t_connection * c, t_packet * packet)
{
	t_packet	* rpacket, * bnpacket;
	char const	* charname;
	char const	* account;
	char            * path;
	t_pdir          * dir;
	t_sq		* sq;
	unsigned int	reply;
	unsigned short	status, class;
	t_d2charinfo_file	data;

	if (!(charname=packet_get_str_const(packet,sizeof(t_client_d2cs_createcharreq),MAX_CHARNAME_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name");
		return -1;
	}
	if (!(account=d2cs_conn_get_account(c))) {
		eventlog(eventlog_level_error,__FUNCTION__,"missing account for character %s",charname);
		return -1;
	}
	class=bn_short_get(packet->u.client_d2cs_createcharreq.class);
	status=bn_short_get(packet->u.client_d2cs_createcharreq.status);

	path=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1);
	d2char_get_infodir_name(path,account);
	if (!(dir=p_opendir(path))) {
	        eventlog(eventlog_level_info,__FUNCTION__,"(*%s) charinfo directory do not exist, building it",account);
		p_mkdir(path,S_IRWXU);
	} else p_closedir(dir);
	xfree(path);

	if (d2char_create(account,charname,class,status)<0) {
		eventlog(eventlog_level_warn,__FUNCTION__,"error create character %s for account %s",charname,account);
		reply=D2CS_CLIENT_CREATECHARREPLY_ALREADY_EXIST;
	} else if (d2charinfo_load(account,charname,&data)<0) {
Ejemplo n.º 2
0
extern int d2char_delete(char const * account, char const * charname)
{
	char		* file;

	ASSERT(account,-1);
	ASSERT(charname,-1);
	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	
	/* charsave file */
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	if (remove(file)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to delete charinfo file \"%s\" (remove: %s)",file,pstrerror(errno));
		xfree(file);
		return -1;
	}
	xfree(file);
	
	/* charinfo file */
	file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
	d2char_get_savefile_name(file,charname);
	if (remove(file)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to delete charsave file \"%s\" (remove: %s)",file,pstrerror(errno));
	}
	xfree(file);
	
	/* bak charsave file */
	file=xmalloc(strlen(prefs_get_bak_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_bak_infofile_name(file,account,charname);
	if (access(file, F_OK) == 0) {
	    if (remove(file)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to delete bak charinfo file \"%s\" (remove: %s)",file,pstrerror(errno));
	    }
	}
	xfree(file);
	
	/* bak charinfo file */
	file=xmalloc(strlen(prefs_get_bak_charsave_dir())+1+strlen(charname)+1);
	d2char_get_bak_savefile_name(file,charname);
	if (access(file, F_OK) == 0) {
	    if (remove(file)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to delete bak charsave file \"%s\" (remove: %s)",file,pstrerror(errno));
	    }
	}
	xfree(file);
	
	eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) deleted",charname,account);
	return 0;
}
Ejemplo n.º 3
0
extern int d2char_get_infodir_name(char * filename, char const * account)
{
	char	tmpacct[MAX_ACCTNAME_LEN];

	ASSERT(filename,-1);
	ASSERT(account,-1);

	strncpy(tmpacct,account,sizeof(tmpacct));
	tmpacct[sizeof(tmpacct)-1]='\0';
	strtolower(tmpacct);
	sprintf(filename,"%s/%s",prefs_get_charinfo_dir(),tmpacct);
	return 0;
}
Ejemplo n.º 4
0
extern int d2char_find(char const * account, char const * charname)
{
	char		* file;
	FILE		* fp;

	ASSERT(account,-1);
	ASSERT(charname,-1);
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	fp=fopen(file,"rb");
	xfree(file);
	if (fp) {
		fclose(fp);
		return 0;
	}
	return -1;
}
Ejemplo n.º 5
0
extern int d2charinfo_load(char const * account, char const * charname, t_d2charinfo_file * data)
{
	char			* file;
	int			size, ladder_time;

	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	size=sizeof(t_d2charinfo_file);
	if (file_read(file,data,&size)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error loading character file %s",file);
		xfree(file);
		return -1;
	}
	if (size!=sizeof(t_d2charinfo_file)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad charinfo file %s (length %d)",charname,size);
		xfree(file);
		return -1;
	}
	d2char_portrait_init(&data->portrait);
	if (d2charinfo_check(data) < 0) {
		xfree(file);
		return -1;
	}
	if (!(charstatus_get_ladder(bn_int_get(data->summary.charstatus)))) {
		bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
		xfree(file);
		return 0;
	}
	ladder_time = prefs_get_ladder_start_time();
	if ((ladder_time > 0) && bn_int_get(data->header.create_time) < ladder_time) {
		char			buffer[MAX_SAVEFILE_SIZE];
		unsigned int		status_offset;
		unsigned char		status;
		unsigned int		charstatus;
		unsigned int		size;
		unsigned int		version;
		unsigned int		checksum;
		FILE			* fp;

		eventlog(eventlog_level_info,__FUNCTION__,"%s(*%s) was created in old ladder season, set to non-ladder", charname, account);
		if (!(fp=fopen(file,"wb"))) {
			eventlog(eventlog_level_error,__FUNCTION__,"charinfo file \"%s\" does not exist for account \"%s\"",file,account);
			xfree(file);
			return 0;
		}
		xfree(file);
		charstatus = bn_int_get(data->summary.charstatus);
		charstatus_set_ladder(charstatus, 0);
		bn_int_set(&data->summary.charstatus, charstatus);

		status=bn_byte_get(data->portrait.status);
		charstatus_set_ladder(status,0);
		bn_byte_set(&data->portrait.status,status);
		bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);

		if (fwrite(data,1,sizeof(*data),fp)!=sizeof(*data)) {
			eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
}
		fclose(fp);

		file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
		d2char_get_savefile_name(file,charname);

		if (!(fp=fopen(file,"rb+"))) {
			eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
			xfree(file);
			return 0;
		}
		xfree(file);
		size=fread(buffer,1,sizeof(buffer),fp);
		if (!feof(fp)) {
			eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
		}
		version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
		if (version>=0x5C) {
			status_offset=D2CHARSAVE_STATUS_OFFSET_109;
		} else {
			status_offset=D2CHARSAVE_STATUS_OFFSET;
		}
		status=bn_byte_get(buffer+status_offset);
		charstatus_set_ladder(status,0);
		/* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
		bn_byte_set((bn_byte *)(buffer+status_offset),status);
		if (version>=0x5C) {
			checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
			bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum);
		}
		fseek(fp,0,SEEK_SET);
		if (fwrite(buffer,1,size,fp)!=size) {
			eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
		}
		fclose(fp);
	} else {
		bn_byte_set(&data->portrait.ladder, 1);
		xfree(file);
	}
	return 0;
}
Ejemplo n.º 6
0
extern int d2char_convert(char const * account, char const * charname)
{
	FILE			* fp;
	char			* file;
	unsigned char		buffer[MAX_SAVEFILE_SIZE];
	unsigned int		status_offset;
	unsigned char		status;
	unsigned int		charstatus;
	t_d2charinfo_file	charinfo;
	unsigned int		size;
	unsigned int		version;
	unsigned int		checksum;

	ASSERT(account,-1);
	ASSERT(charname,-1);

/*	Playing with a expanstion char on a classic realm
	will cause the game server to crash, therefore
	I recommed setting allow_convert = 0 in the d2cs.conf
	We need to do this to prevent creating classic char
	and converting to expantion on a classic realm.
	LOD Char must be created on LOD realm	*/
		
	if (!prefs_get_allow_convert()) {
		eventlog(eventlog_level_info,__FUNCTION__,"Convert char has been disabled");
		return -1;
	}

/*	Procedure is stopped here and returned if
	allow_convet = 0 in d2cs.conf */
		
	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	if (!(fp=fopen(file,"rb+"))) {
		eventlog(eventlog_level_error,__FUNCTION__,"unable to open charinfo file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
		xfree(file);
		return -1;
	}
	xfree(file);
	if (fread(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error reading charinfo file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	charstatus=bn_int_get(charinfo.summary.charstatus);
	charstatus_set_expansion(charstatus,1);
	bn_int_set(&charinfo.summary.charstatus,charstatus);
	
	status=bn_byte_get(charinfo.portrait.status);
	charstatus_set_expansion(status,1);
	bn_byte_set(&charinfo.portrait.status,status);
	
	fseek(fp,0,SEEK_SET); /* FIXME: check return */
	if (fwrite(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	if (fclose(fp)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not close charinfo file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
		return -1;
	}
	
	file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
	d2char_get_savefile_name(file,charname);
	if (!(fp=fopen(file,"rb+"))) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
		xfree(file);
		return -1;
	}
	xfree(file);
	size=fread(buffer,1,sizeof(buffer),fp);
	if (!feof(fp)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
	if (version>=0x0000005C) {
		status_offset=D2CHARSAVE_STATUS_OFFSET_109;
	} else {
		status_offset=D2CHARSAVE_STATUS_OFFSET;
	}
	status=bn_byte_get(buffer+status_offset);
	charstatus_set_expansion(status,1);
	bn_byte_set((bn_byte *)(buffer+status_offset),status); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
	if (version>=0x0000005C) {
		checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
		bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
	}
	fseek(fp,0,SEEK_SET); /* FIXME: check return */
	if (fwrite(buffer,1,size,fp)!=size) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	if (fclose(fp)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not close charsave file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
		return -1;
	}
	eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) converted to expansion",charname,account);
	return 0;
}
Ejemplo n.º 7
0
extern int d2char_create(char const * account, char const * charname, unsigned char classs, unsigned short status)
{
	t_d2charinfo_file	chardata;
	char			* savefile, * infofile;
	char			buffer[1024];
	unsigned int		size;
	int			ladder_time, now;
	FILE			* fp;


	ASSERT(account,-1);
	ASSERT(charname,-1);
	if (classs>D2CHAR_MAX_CLASS) classs=0;
	status &= D2CHARINFO_STATUS_FLAG_INIT_MASK;
	charstatus_set_init(status,1);
	
/*	We need to make sure we are creating the correct character (Classic or Expansion)
	for the type of game server we are running. If lod_realm = 1 then only Expansion
	characters can be created and if set to 0 then only Classic character can
	be created	*/
	
	if (!(prefs_get_lod_realm() == 2)) {
		if (prefs_get_lod_realm() && ((status & 0x20) != 0x20)) {
		    eventlog(eventlog_level_warn,__FUNCTION__,"This Realm is for LOD Characters Only");
		    return -1;
		}
		if (!prefs_get_lod_realm() && ((status & 0x20) != 0x0)) {
		    eventlog(eventlog_level_warn,__FUNCTION__,"This Realm is for Classic Characters Only");
		    return -1;
		}
	}
	
/*	Once correct type of character is varified then continue with creation of character */	
	
	if (!prefs_allow_newchar()) {
		eventlog(eventlog_level_warn,__FUNCTION__,"creation of new_ character is disabled");
		return -1;
	}
	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	size=sizeof(buffer);
	if (file_read(prefs_get_charsave_newbie(), buffer, &size)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error loading newbie save file");
		return -1;
	}
	if (size>=sizeof(buffer)) {
		eventlog(eventlog_level_error,__FUNCTION__,"newbie save file \"%s\" is corrupt (length %lu, expected <%lu)",prefs_get_charsave_newbie(),(unsigned long)size,(unsigned long)sizeof(buffer));
		return -1;
	}

	savefile=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
	d2char_get_savefile_name(savefile,charname);
	if ((fp=fopen(savefile,"rb"))) {
		eventlog(eventlog_level_warn,__FUNCTION__,"character save file \"%s\" for \"%s\" already exist",savefile,charname);
		fclose(fp);
		xfree(savefile);
		return -1;
	}
	
	infofile=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(infofile,account,charname);

	now = time(NULL);
	ladder_time = prefs_get_ladder_start_time();
	if ((ladder_time > 0) && (now < ladder_time))
		charstatus_set_ladder(status, 0);
	
	d2charsave_init(buffer,charname,classs,status);
	d2charinfo_init(&chardata,account,charname,classs,status);

	if (file_write(infofile,&chardata,sizeof(chardata))<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing info file \"%s\"",infofile);
		remove(infofile);
		xfree(infofile);
		xfree(savefile);
		return -1;
	}

	if (file_write(savefile,buffer,size)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing save file \"%s\"",savefile);
		remove(infofile);
		remove(savefile);
		xfree(savefile);
		xfree(infofile);
		return -1;
	}
	xfree(savefile);
	xfree(infofile);
	eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) classs %d status 0x%X created",charname,account,classs,status);
	return 0;
}