diff options
-rw-r--r-- | Changelog-Trunk.txt | 6 | ||||
-rw-r--r-- | conf/char_athena.conf | 2 | ||||
-rw-r--r-- | db/packet_db.txt | 5 | ||||
-rw-r--r-- | npc/merchants/advanced_refiner.txt | 465 | ||||
-rw-r--r-- | sql-files/upgrade_svn11388.sql | 8 | ||||
-rw-r--r-- | sql-files/upgrade_svn11548.sql | 29 | ||||
-rw-r--r-- | src/char/int_guild.c | 4 | ||||
-rw-r--r-- | src/char/inter.c | 10 | ||||
-rw-r--r-- | src/char_sql/char.c | 14 | ||||
-rw-r--r-- | src/char_sql/int_mail.c | 295 | ||||
-rw-r--r-- | src/char_sql/int_mail.h | 24 | ||||
-rw-r--r-- | src/common/malloc.h | 2 | ||||
-rw-r--r-- | src/common/mmo.h | 12 | ||||
-rw-r--r-- | src/common/socket.c | 2 | ||||
-rw-r--r-- | src/map/chat.c | 8 | ||||
-rw-r--r-- | src/map/clif.c | 143 | ||||
-rw-r--r-- | src/map/clif.h | 2 | ||||
-rw-r--r-- | src/map/guild.c | 57 | ||||
-rw-r--r-- | src/map/intif.c | 156 | ||||
-rw-r--r-- | src/map/npc.c | 13 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/skill.c | 17 | ||||
-rw-r--r-- | vcproj-6/char-server_sql.dsp | 8 | ||||
-rw-r--r-- | vcproj-7.1/char-server_sql.vcproj | 6 |
24 files changed, 644 insertions, 646 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index a35430c4a..0890fc636 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,12 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2007/10/24 + * Increased the max. send buffer size to 5M since 1M is not enough + * Updated vs7 and vs6 project files + * Added upgrade_svn11548.sql to convert the mail table to new format + * Cleaned up the mail code, no more pointless dynamic allocation + * Cleaned up some messy guild code (more to come) [ultramage] 2007/10/23 * Fixed a compilation bug on linux (FALSE -> false) [Zephyrus] 2007/10/22 diff --git a/conf/char_athena.conf b/conf/char_athena.conf index 200831220..a9848422e 100644 --- a/conf/char_athena.conf +++ b/conf/char_athena.conf @@ -146,7 +146,7 @@ char_log_filename: log/char.log // Allow or not identical name for characters but with a different case (upper/lower): // example: Test-test-TEST-TesT; Value: 0 not allowed (default), 1 allowed -name_ignoring_case: 0 +name_ignoring_case: no // Manage possible letters/symbol in the name of charater. Control character (0x00-0x1f) are never accepted. Possible values are: // NOTE: Applies to character, party and guild names. diff --git a/db/packet_db.txt b/db/packet_db.txt index ccdd2a17e..b1b9c81f9 100644 --- a/db/packet_db.txt +++ b/db/packet_db.txt @@ -753,7 +753,6 @@ packet_ver: 18 0x0116,12,dropitem,6:10 0x0190,21,actionrequest,5:20 0x0216,6 -//Start mail system? 0x023f,2,mailrefresh,0 0x0240,8 0x0241,6,mailread,2 @@ -761,13 +760,9 @@ packet_ver: 18 0x0243,6,maildelete,2 0x0244,6,mailgetattach,2 0x0245,7 -//Start writing a mail? 0x0246,4,mailwinopen,2 -//Send Item/Zeny 0x0247,8,mailsetattach,2:4 -//Message 0x0248,68 -//Delivered? 0x0249,3 0x024a,70 0x024b,4 diff --git a/npc/merchants/advanced_refiner.txt b/npc/merchants/advanced_refiner.txt index 2620dccfb..bf6ba05ef 100644 --- a/npc/merchants/advanced_refiner.txt +++ b/npc/merchants/advanced_refiner.txt @@ -1,232 +1,233 @@ -//===== eAthena Script =======================================
-//= Advanced Refiner
-//===== By: ==================================================
-//= L0ne_W0lf
-//===== Current Version: =====================================
-//= 1.0
-//===== Compatible With: =====================================
-//= Eathena SVN
-//===== Description: =========================================
-//= [Aegis Conversion]
-//= Refiner that uses Enriched ores to increase upgrade
success.
-//= After a conversation with Doddler, it's been established that
-//= the advanced refiner works similar the the "Bubble Gum" item.
-//= The success percentage is not "increased" however, if it fails
-//= You get a second try. This tries twice at the same time,
-//= effectively giving you a re-roll on your attempt.
-//= - Dialog is only partly official to iRO.
-//= - Uses the iRO position for this NPC.
-//===== Additional Comments: =================================
-//= 1.0 First Version. [L0ne_W0lf]
-//============================================================
-
-payon,174,138,0 script Suhnbi#cash 85,{
- mes "[Suhnbi]";
- mes "I am the Armsith";
- mes "I can refine all kinds of weapons,";
- mes "armor and equipment, so let me";
- mes "know what you want to refine.";
- next;
- set .@strRetPart1$,getequipname(1);
- set .@strRetPart2$,getequipname(2);
- set .@strRetPart3$,getequipname(3);
- set .@strRetPart4$,getequipname(4);
- set .@strRetPart5$,getequipname(5);
- set .@strRetPart6$,getequipname(6);
- set .@strRetPart7$,getequipname(7);
- set .@strRetPart8$,getequipname(8);
- set .@strRetPart9$,getequipname(9);
- set .@strRetPart10$,getequipname(10);
-
- set .@menu$,.@strRetPart1$+":"+.@strRetPart2$+":"+.@strRetPart3$+":"+.@strRetPart4$+":"+.@strRetPart5$+":"+.@strRetPart6$+":"+.@strRetPart7$+":"+.@strRetPart8$+":"+.@strRetPart9$+":"+.@strRetPart10$;
-
- switch(select(.@menu$)) {
- case 1:
- set .@part,1;
- if (getequipisequiped(1) == 0) {
- mes "[Suhnbi]";
- mes "Do you want me to refine your skull?";
- close;
- }
- break;
- case 2:
- set .@part,2;
- if (getequipisequiped(2) == 0) {
- mes "[Suhnbi]";
- mes "I'll refine your torso with my own passionate body!";
- close;
- }
- break;
- case 3:
- set .@part,3;
- if (getequipisequiped(3) == 0) {
- mes "[Suhnbi]";
- mes "Sorry, there ain't any technology yet to put rockets on your left hand...";
- close;
- }
- break;
- case 4:
- set .@part,4;
- if (getequipisequiped(4) == 0) {
- mes "[Suhnbi]";
- mes "Sorry, there ain't any technology yet to put rockets on your right hand...";
- close;
- }
- break;
- case 5:
- set .@part,5;
- if (getequipisequiped(5) == 0) {
- mes "[Suhnbi]";
- mes "You're not even wearing a garment? Are you?";
- close;
- }
- break;
- case 6:
- set .@part,6;
- if (getequipisequiped(6) == 0) {
- mes "[Suhnbi]";
- mes "What do I look like, a makeover artist? I can't refine your bare feet!";
- close;
- }
- break;
- case 7:
- set .@part,7;
- if (getequipisequiped(7) == 0) {
- mes "[Suhnbi]";
- mes "Um... You're not wearing an Accessory.";
- close;
- }
- break;
- case 8:
- set .@part,8;
- if (getequipisequiped(8) == 0) {
- mes "[Suhnbi]";
- mes "Accessory? You're not wearing one of those.";
- close;
- }
- break;
- case 9:
- set .@part,9;
- if (getequipisequiped(9) == 0) {
- mes "[Suhnbi]";
- mes "I refine equipment. I don't give hair cuts.";
- close;
- }
- break;
- case 10:
- set .@part,10;
- if (getequipisequiped(10) == 0) {
- mes "[Suhnbi]";
- mes "What am I, your personal hairstylist?. Go to the salon if you want work done on your precious hair.";
- close2;
- }
- break;
- }
-
- if (getequipisenableref(.@part) == 0) {
- mes "[Suhnbi]";
- mes "I don't think I can refine this item at all.";
- close;
- }
- if (getequipisidentify(.@part) == 0) {
- mes "[Suhnbi]";
- mes "This is has not been identified. So, it can't be refined...";
- close;
- }
- if (getequiprefinerycnt(.@part) >= 10) {
- mes "[Suhnbi]";
- mes "This item cannot be refined because it has already reached its maximum level...";
- close;
- }
- // Make sure you have the neccessary items and Zeny to refine your items
- // Determines chance of failure and verifies that you want to continue.
- switch(getequipweaponlv(.@part)) {
- case 1: callsub S_RefineValidate,1,7620,50,.@part; break;
- case 2: callsub S_RefineValidate,2,7620,200,.@part; break;
- case 3: callsub S_RefineValidate,3,7620,5000,.@part; break;
- case 4: callsub S_RefineValidate,4,7620,20000,.@part; break;
- default: callsub S_RefineValidate,0,7619,2000,.@part; break;
- }
-
- if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
- mes "[Suhnbi]";
- mes "Clink! Clank! Clunk!";
- SuccessRefItem .@part;
- next;
- Emotion e_no1;
- mes "[Suhnbi]";
- mes "Here you are! It's done.";
- mes "It's been a while since I've made such a fine weapon. You must be happy because it has become stronger!";
- close;
- }
- else {
- mes "[Suhnbi]";
- mes "Clink! Clank! Clunk!";
- FailedRefItem .@part;
- next;
- if (rand(5) == 1)
- Emotion e_cash;
- else
- Emotion e_omg;
- mes "[Suhnbi]";
- mes "Cough!!!!";
- next;
- mes "[Suhnbi]";
- mes "Cough...Cough..";
- mes "What a shame...";
- mes "Your equipment broke during hte refining process. I had told you earlier this might happen!";
- close;
- }
-
-S_RefineValidate:
- mes "[Suhnbi]";
- if (getarg(0))
- mes "A level "+getarg(0)+" weapon...";
- mes "To refine this I need one ^ff9999"+getitemname(getarg(1))+"^000000 and a service fee of "+getarg(2)+" Zeny.";
- mes "Do you wish to continue?";
- next;
- if (select("Yes:No") == 1) {
- if (getequippercentrefinery(getarg(3)) < 100) {
- mes "[Suhnbi]";
- mes "Wow!!";
- mes "This weapon, probably";
- mes "looks like it's been refined...";
- mes "many times...";
- mes "It may break if";
- mes "you refine it again.";
- next;
- mes "And if it breaks,";
- mes "you can't use it anymore!";
- mes "All the cards in it and the";
- mes "properties";
- mes "^ff0000will be lost^000000!!";
- mes "^ff0000 besides, the equipment will break!^000000";
- mes " ";
- mes "Are you sure you still want to continue?";
- next;
- if (select("Yes:No") == 2) {
- mes "[Suhnbi]";
- mes "I completely agree...";
- mes "I might be a great refiner, but something even I make mistakes.";
- close;
- }
- }
- if (countitem(getarg(1)) > 0 && Zeny > getarg(2)) {
- delitem getarg(1),1;
- set zeny,zeny-getarg(2);
- return;
- }
- else {
- mes "[Suhnbi]";
- mes "You don't seem to have enough Zeny or "+getitemname(getarg(1))+"...";
- mes "Go get some more. I'll be here ll day if you need me.";
- close;
- }
- }
- else {
- mes "[Suhnbi]";
- mes "Yeah... There's no need to rush.";
- mes "Take your time.";
- close;
- }
-}
+//===== eAthena Script ======================================= +//= Advanced Refiner +//===== By: ================================================== +//= L0ne_W0lf +//===== Current Version: ===================================== +//= 1.0 +//===== Compatible With: ===================================== +//= Eathena SVN +//===== Description: ========================================= +//= [Aegis Conversion] +//= Refiner that uses Enriched ores to increase upgrade + success. +//= After a conversation with Doddler, it's been established that +//= the advanced refiner works similar the the "Bubble Gum" item. +//= The success percentage is not "increased" however, if it fails +//= You get a second try. This tries twice at the same time, +//= effectively giving you a re-roll on your attempt. +//= - Dialog is only partly official to iRO. +//= - Uses the iRO position for this NPC. +//===== Additional Comments: ================================= +//= 1.0 First Version. [L0ne_W0lf] +//============================================================ + +payon,174,138,0 script Suhnbi#cash 85,{ + mes "[Suhnbi]"; + mes "I am the Armsith"; + mes "I can refine all kinds of weapons,"; + mes "armor and equipment, so let me"; + mes "know what you want to refine."; + next; + set .@strRetPart1$,getequipname(1); + set .@strRetPart2$,getequipname(2); + set .@strRetPart3$,getequipname(3); + set .@strRetPart4$,getequipname(4); + set .@strRetPart5$,getequipname(5); + set .@strRetPart6$,getequipname(6); + set .@strRetPart7$,getequipname(7); + set .@strRetPart8$,getequipname(8); + set .@strRetPart9$,getequipname(9); + set .@strRetPart10$,getequipname(10); + + set .@menu$,.@strRetPart1$+":"+.@strRetPart2$+":"+.@strRetPart3$+":"+.@strRetPart4$+":"+.@strRetPart5$+":"+.@strRetPart6$+":"+.@strRetPart7$+":"+.@strRetPart8$+":"+.@strRetPart9$+":"+.@strRetPart10$; + + switch(select(.@menu$)) { + case 1: + set .@part,1; + if (getequipisequiped(1) == 0) { + mes "[Suhnbi]"; + mes "Do you want me to refine your skull?"; + close; + } + break; + case 2: + set .@part,2; + if (getequipisequiped(2) == 0) { + mes "[Suhnbi]"; + mes "I'll refine your torso with my own passionate body!"; + close; + } + break; + case 3: + set .@part,3; + if (getequipisequiped(3) == 0) { + mes "[Suhnbi]"; + mes "Sorry, there ain't any technology yet to put rockets on your left hand..."; + close; + } + break; + case 4: + set .@part,4; + if (getequipisequiped(4) == 0) { + mes "[Suhnbi]"; + mes "Sorry, there ain't any technology yet to put rockets on your right hand..."; + close; + } + break; + case 5: + set .@part,5; + if (getequipisequiped(5) == 0) { + mes "[Suhnbi]"; + mes "You're not even wearing a garment? Are you?"; + close; + } + break; + case 6: + set .@part,6; + if (getequipisequiped(6) == 0) { + mes "[Suhnbi]"; + mes "What do I look like, a makeover artist? I can't refine your bare feet!"; + close; + } + break; + case 7: + set .@part,7; + if (getequipisequiped(7) == 0) { + mes "[Suhnbi]"; + mes "Um... You're not wearing an Accessory."; + close; + } + break; + case 8: + set .@part,8; + if (getequipisequiped(8) == 0) { + mes "[Suhnbi]"; + mes "Accessory? You're not wearing one of those."; + close; + } + break; + case 9: + set .@part,9; + if (getequipisequiped(9) == 0) { + mes "[Suhnbi]"; + mes "I refine equipment. I don't give hair cuts."; + close; + } + break; + case 10: + set .@part,10; + if (getequipisequiped(10) == 0) { + mes "[Suhnbi]"; + mes "What am I, your personal hairstylist?. Go to the salon if you want work done on your precious hair."; + close2; + } + break; + } + + if (getequipisenableref(.@part) == 0) { + mes "[Suhnbi]"; + mes "I don't think I can refine this item at all."; + close; + } + if (getequipisidentify(.@part) == 0) { + mes "[Suhnbi]"; + mes "This is has not been identified. So, it can't be refined..."; + close; + } + if (getequiprefinerycnt(.@part) >= 10) { + mes "[Suhnbi]"; + mes "This item cannot be refined because it has already reached its maximum level..."; + close; + } + // Make sure you have the neccessary items and Zeny to refine your items + // Determines chance of failure and verifies that you want to continue. + switch(getequipweaponlv(.@part)) { + case 1: callsub S_RefineValidate,1,7620,50,.@part; break; + case 2: callsub S_RefineValidate,2,7620,200,.@part; break; + case 3: callsub S_RefineValidate,3,7620,5000,.@part; break; + case 4: callsub S_RefineValidate,4,7620,20000,.@part; break; + default: callsub S_RefineValidate,0,7619,2000,.@part; break; + } + + if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + mes "[Suhnbi]"; + mes "Clink! Clank! Clunk!"; + SuccessRefItem .@part; + next; + Emotion e_no1; + mes "[Suhnbi]"; + mes "Here you are! It's done."; + mes "It's been a while since I've made such a fine weapon. You must be happy because it has become stronger!"; + close; + } + else { + mes "[Suhnbi]"; + mes "Clink! Clank! Clunk!"; + FailedRefItem .@part; + next; + if (rand(5) == 1) + Emotion e_cash; + else + Emotion e_omg; + mes "[Suhnbi]"; + mes "Cough!!!!"; + next; + mes "[Suhnbi]"; + mes "Cough...Cough.."; + mes "What a shame..."; + mes "Your equipment broke during hte refining process. I had told you earlier this might happen!"; + close; + } + +S_RefineValidate: + mes "[Suhnbi]"; + if (getarg(0)) + mes "A level "+getarg(0)+" weapon..."; + mes "To refine this I need one ^ff9999"+getitemname(getarg(1))+"^000000 and a service fee of "+getarg(2)+" Zeny."; + mes "Do you wish to continue?"; + next; + if (select("Yes:No") == 1) { + if (getequippercentrefinery(getarg(3)) < 100) { + mes "[Suhnbi]"; + mes "Wow!!"; + mes "This weapon, probably"; + mes "looks like it's been refined..."; + mes "many times..."; + mes "It may break if"; + mes "you refine it again."; + next; + mes "And if it breaks,"; + mes "you can't use it anymore!"; + mes "All the cards in it and the"; + mes "properties"; + mes "^ff0000will be lost^000000!!"; + mes "^ff0000 besides, the equipment will break!^000000"; + mes " "; + mes "Are you sure you still want to continue?"; + next; + if (select("Yes:No") == 2) { + mes "[Suhnbi]"; + mes "I completely agree..."; + mes "I might be a great refiner, but something even I make mistakes."; + close; + } + } + if (countitem(getarg(1)) > 0 && Zeny > getarg(2)) { + delitem getarg(1),1; + set zeny,zeny-getarg(2); + return; + } + else { + mes "[Suhnbi]"; + mes "You don't seem to have enough Zeny or "+getitemname(getarg(1))+"..."; + mes "Go get some more. I'll be here ll day if you need me."; + close; + } + } + else { + mes "[Suhnbi]"; + mes "Yeah... There's no need to rush."; + mes "Take your time."; + close; + } +} diff --git a/sql-files/upgrade_svn11388.sql b/sql-files/upgrade_svn11388.sql index 5393ca861..8ca4d0fbb 100644 --- a/sql-files/upgrade_svn11388.sql +++ b/sql-files/upgrade_svn11388.sql @@ -1,5 +1,5 @@ -ALTER TABLE `atcommandlog` CHANGE `command` `command` VARCHAR( 255 ) NOT NULL;
-ALTER TABLE `atcommandlog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL;
-ALTER TABLE `branchlog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL;
-ALTER TABLE `npclog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL;
+ALTER TABLE `atcommandlog` CHANGE `command` `command` VARCHAR( 255 ) NOT NULL; +ALTER TABLE `atcommandlog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL; +ALTER TABLE `branchlog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL; +ALTER TABLE `npclog` CHANGE `char_name` `char_name` VARCHAR( 25 ) NOT NULL;
\ No newline at end of file diff --git a/sql-files/upgrade_svn11548.sql b/sql-files/upgrade_svn11548.sql new file mode 100644 index 000000000..722806f12 --- /dev/null +++ b/sql-files/upgrade_svn11548.sql @@ -0,0 +1,29 @@ +-- this will covert the old `mail` table to new format, convert columns and fill in default values -- + +-- change structure -- +ALTER TABLE `mail` CHANGE `message_id` `id` bigint(20) unsigned NOT NULL auto_increment; +ALTER TABLE `mail` CHANGE `from_char_name` `send_name` varchar(30) NOT NULL default '' AFTER `id`; +ALTER TABLE `mail` CHANGE `from_account_id` `send_id` int(11) unsigned NOT NULL default 0 AFTER `send_name`; +ALTER TABLE `mail` CHANGE `to_char_name` `dest_name` varchar(30) NOT NULL default '' AFTER `send_id`; +ALTER TABLE `mail` CHANGE `to_account_id` `dest_id` int(11) unsigned NOT NULL default 0 AFTER `dest_name`; +ALTER TABLE `mail` ADD `title` varchar(45) NOT NULL default '' AFTER `dest_id`; +ALTER TABLE `mail` CHANGE `message` `message` varchar(255) NOT NULL default '' AFTER `title`; +ALTER TABLE `mail` ADD `time` int(11) unsigned NOT NULL default 0 AFTER `message`; +ALTER TABLE `mail` CHANGE `read_flag` `read_flag` tinyint(1) NOT NULL default 0 AFTER `time`; +ALTER TABLE `mail` ADD `zeny` int(11) unsigned NOT NULL default 0 AFTER `read_flag`; +ALTER TABLE `mail` ADD `nameid` int(11) unsigned NOT NULL default 0 AFTER `zeny`; +ALTER TABLE `mail` ADD `amount` int(11) unsigned NOT NULL default 0 AFTER `nameid`; +ALTER TABLE `mail` ADD `refine` tinyint(3) unsigned NOT NULL default 0 AFTER `amount`; +ALTER TABLE `mail` ADD `attribute` tinyint(4) unsigned NOT NULL default 0 AFTER `refine`; +ALTER TABLE `mail` ADD `identify` smallint(6) NOT NULL default 0 AFTER `attribute`; +ALTER TABLE `mail` ADD `card0` smallint(11) NOT NULL default 0 AFTER `identify`; +ALTER TABLE `mail` ADD `card1` smallint(11) NOT NULL default 0 AFTER `card0`; +ALTER TABLE `mail` ADD `card2` smallint(11) NOT NULL default 0 AFTER `card1`; +ALTER TABLE `mail` ADD `card3` smallint(11) NOT NULL default 0 AFTER `card2`; +ALTER TABLE `mail` DROP `priority`; +ALTER TABLE `mail` DROP `check_flag`; + +-- correct values in some columns -- +UPDATE `mail` SET `time` = UNIX_TIMESTAMP(NOW()); +UPDATE `mail` SET `send_id` = (SELECT `char_id` FROM `char` WHERE `name` = `send_name`); +UPDATE `mail` SET `dest_id` = (SELECT `char_id` FROM `char` WHERE `name` = `dest_name`); diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 2bf3e0a41..235ddc77a 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -1516,9 +1516,7 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le g->member[pos].position = g->member[0].position; g->member[0].position = 0; //Position 0: guild Master. - strncpy(g->master, name, len); - if (len < NAME_LENGTH) - g->master[len] = '\0'; + safestrncpy(g->master, name, NAME_LENGTH); ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",name, guild_id, g->name); return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id); diff --git a/src/char/inter.c b/src/char/inter.c index 6c877de71..9856c13b2 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -53,12 +53,12 @@ int inter_recv_packet_length[]={ 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, //0x3010-0x301f -1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, //0x3020-0x302f -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1, //0x3030-0x303f - 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3040-0x304f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3050-0x305f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3060-0x306f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3070-0x307f 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3080-0x308f - -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator] + -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3090-0x309f Homunculus packets [albator] }; struct WisData { diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 649d4c368..5d5f04653 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -3205,13 +3205,13 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) int i; if (fd >= 0) { - for(i = 0; i < MAX_MAP_SERVERS; i++) { - if (fd == server_fd[i]) { - WFIFOHEAD(fd,len); - memcpy(WFIFOP(fd,0), buf, len); - WFIFOSET(fd,len); - return 1; - } + ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server_fd[i] ); + if( i < MAX_MAP_SERVERS ) + { + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); + return 1; } } return 0; diff --git a/src/char_sql/int_mail.c b/src/char_sql/int_mail.c index 00d79d91f..b1a1bff5f 100644 --- a/src/char_sql/int_mail.c +++ b/src/char_sql/int_mail.c @@ -14,15 +14,14 @@ #include <string.h> #include <stdlib.h> -struct mail_data *mail_data_pt = NULL; - -time_t calc_times(void) +static time_t calc_times(void) { time_t temp = time(NULL); return mktime(localtime(&temp)); } -int mail_fromsql(int char_id, struct mail_data *md) + +static int mail_fromsql(int char_id, struct mail_data* md) { int i, j; struct mail_message *msg; @@ -80,11 +79,11 @@ int mail_fromsql(int char_id, struct mail_data *md) Sql_FreeResult(sql_handle); md->unchecked = 0; - md->unreaded = 0; + md->unread = 0; for (i = 0; i < md->amount; i++) { msg = &md->msg[i]; - if (!msg->read) + if( msg->read == 0 ) { if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '1' WHERE `id` = '%d'", mail_db, msg->id) ) Sql_ShowDebug(sql_handle); @@ -92,7 +91,7 @@ int mail_fromsql(int char_id, struct mail_data *md) md->unchecked++; } else if ( msg->read == 1 ) - md->unreaded++; + md->unread++; msg->read = (msg->read < 2)?0:1; } @@ -101,151 +100,144 @@ int mail_fromsql(int char_id, struct mail_data *md) return 1; } -int mail_savemessage(struct mail_message *msg) +/// Stores a single message in the database. +/// Returns the message's ID if successful (or 0 if it fails). +static int mail_savemessage(struct mail_message* msg) { StringBuf buf; + SqlStmt* stmt; int j; - char esc_send_name[NAME_LENGTH*2+1], esc_dest_name[NAME_LENGTH*2+1]; - char esc_title[MAIL_TITLE_LENGTH*2+1], esc_body[MAIL_BODY_LENGTH*2+1]; - - if (!msg) - return 0; - - Sql_EscapeStringLen(sql_handle, esc_send_name, msg->send_name, strnlen(msg->send_name, NAME_LENGTH)); - Sql_EscapeStringLen(sql_handle, esc_dest_name, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)); - Sql_EscapeStringLen(sql_handle, esc_title, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH)); - Sql_EscapeStringLen(sql_handle, esc_body, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH)); + // build message save query StringBuf_Init(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `read_flag`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`", mail_db); for (j = 0; j < MAX_SLOTS; j++) StringBuf_Printf(&buf, ", `card%d`", j); - StringBuf_Printf(&buf, ") VALUES ('%s', '%d', '%s', '%d', '%s', '%s', '%d', '0', '%d', '%d', '%d', '%d', '%d', '%d'", - esc_send_name, msg->send_id, esc_dest_name, msg->dest_id, esc_title, esc_body, msg->timestamp, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify); + StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%d', '0', '%d', '%d', '%d', '%d', '%d', '%d'", + msg->send_id, msg->dest_id, msg->timestamp, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify); for (j = 0; j < MAX_SLOTS; j++) StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]); StringBuf_AppendStr(&buf, ")"); - if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + // prepare and execute query + stmt = SqlStmt_Malloc(sql_handle); + if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) + || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH)) + || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)) + || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, NAME_LENGTH)) + || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, NAME_LENGTH)) + || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { Sql_ShowDebug(sql_handle); j = 0; - } - else + } else j = (int)Sql_LastInsertId(sql_handle); StringBuf_Destroy(&buf); + // return the ID of the new mail return j; } -int mail_loadmessage(int char_id, int mail_id, struct mail_message *message, short flag) +/// Retrieves a single message from the database. +/// Returns true if the operation succeeds (or false if it fails). +static bool mail_loadmessage(int char_id, int mail_id, struct mail_message* msg) { - char *data; - struct item *item; - int j = 0; + int j; StringBuf buf; StringBuf_Init(&buf); StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`read_flag`," "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`"); - for (j = 0; j < MAX_SLOTS; j++) + for( j = 0; j < MAX_SLOTS; j++ ) StringBuf_Printf(&buf, ",`card%d`", j); StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id` = '%d' AND `id` = '%d'", mail_db, char_id, mail_id); - if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) ) + if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) + || SQL_SUCCESS != Sql_NextRow(sql_handle) ) + { Sql_ShowDebug(sql_handle); - else if( Sql_NumRows(sql_handle) == 0 ) - ShowWarning("Char %d trying to read an invalid mail.\n", char_id); + Sql_FreeResult(sql_handle); + StringBuf_Destroy(&buf); + return false; + } else { - Sql_NextRow(sql_handle); - - Sql_GetData(sql_handle, 0, &data, NULL); message->id = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(message->send_name, data, NAME_LENGTH); - Sql_GetData(sql_handle, 2, &data, NULL); message->send_id = atoi(data); - Sql_GetData(sql_handle, 3, &data, NULL); safestrncpy(message->dest_name, data, NAME_LENGTH); - Sql_GetData(sql_handle, 4, &data, NULL); message->dest_id = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(message->title, data, MAIL_TITLE_LENGTH); - Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(message->body, data, MAIL_BODY_LENGTH); - Sql_GetData(sql_handle, 7, &data, NULL); message->timestamp = atoi(data); - Sql_GetData(sql_handle, 8, &data, NULL); message->read = atoi(data); - Sql_GetData(sql_handle, 9, &data, NULL); message->zeny = atoi(data); - item = &message->item; - Sql_GetData(sql_handle,10, &data, NULL); item->amount = (short)atoi(data); - Sql_GetData(sql_handle,11, &data, NULL); item->nameid = atoi(data); - Sql_GetData(sql_handle,12, &data, NULL); item->refine = atoi(data); - Sql_GetData(sql_handle,13, &data, NULL); item->attribute = atoi(data); - Sql_GetData(sql_handle,14, &data, NULL); item->identify = atoi(data); - for (j = 0; j < MAX_SLOTS; j++) + char* data; + + Sql_GetData(sql_handle, 0, &data, NULL); msg->id = atoi(data); + Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(msg->send_name, data, NAME_LENGTH); + Sql_GetData(sql_handle, 2, &data, NULL); msg->send_id = atoi(data); + Sql_GetData(sql_handle, 3, &data, NULL); safestrncpy(msg->dest_name, data, NAME_LENGTH); + Sql_GetData(sql_handle, 4, &data, NULL); msg->dest_id = atoi(data); + Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH); + Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH); + Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data); + Sql_GetData(sql_handle, 8, &data, NULL); msg->read = atoi(data); + Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data); + Sql_GetData(sql_handle,10, &data, NULL); msg->item.amount = (short)atoi(data); + Sql_GetData(sql_handle,11, &data, NULL); msg->item.nameid = atoi(data); + Sql_GetData(sql_handle,12, &data, NULL); msg->item.refine = atoi(data); + Sql_GetData(sql_handle,13, &data, NULL); msg->item.attribute = atoi(data); + Sql_GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data); + for( j = 0; j < MAX_SLOTS; j++ ) { Sql_GetData(sql_handle,15 + j, &data, NULL); - item->card[j] = atoi(data); + msg->item.card[j] = atoi(data); } - - j = 1; } StringBuf_Destroy(&buf); Sql_FreeResult(sql_handle); - if (message->read == 1) + ShowDebug("Loaded message (had read flag %d)\n", msg->read); + if (msg->read == 1) { - message->read = 0; - if (flag) - if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '2' WHERE `id` = '%d'", mail_db, message->id) ) - Sql_ShowDebug(sql_handle); + msg->read = 0; } else - message->read = 1; + msg->read = 1; - return j; + return true; } /*========================================== * Client Inbox Request *------------------------------------------*/ -int mapif_Mail_sendinbox(int fd, int char_id, unsigned char flag) +static void mapif_Mail_sendinbox(int fd, int char_id, unsigned char flag) { - WFIFOHEAD(fd, sizeof(struct mail_data) + 9); - mail_fromsql(char_id, mail_data_pt); + struct mail_data md; + mail_fromsql(char_id, &md); + + //FIXME: dumping the whole structure like this is unsafe [ultramage] + WFIFOHEAD(fd, sizeof(md) + 9); WFIFOW(fd,0) = 0x3848; - WFIFOW(fd,2) = sizeof(struct mail_data) + 9; + WFIFOW(fd,2) = sizeof(md) + 9; WFIFOL(fd,4) = char_id; WFIFOB(fd,8) = flag; - memcpy(WFIFOP(fd,9),mail_data_pt,sizeof(struct mail_data)); + memcpy(WFIFOP(fd,9),&md,sizeof(md)); WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; } -int mapif_parse_Mail_requestinbox(int fd) +static void mapif_parse_Mail_requestinbox(int fd) { - RFIFOHEAD(fd); mapif_Mail_sendinbox(fd, RFIFOL(fd,2), RFIFOB(fd,6)); - - return 0; } /*========================================== - * Mail Readed Mark + * 'Mail read' Mark *------------------------------------------*/ -int mapif_parse_Mail_read(int fd) +static void mapif_parse_Mail_read(int fd) { - int mail_id; - RFIFOHEAD(fd); - - mail_id = RFIFOL(fd,2); + int mail_id = RFIFOL(fd,2); if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '2' WHERE `id` = '%d'", mail_db, mail_id) ) Sql_ShowDebug(sql_handle); - - return 0; } /*========================================== * Client Attachment Request *------------------------------------------*/ -int mail_DeleteAttach(int mail_id) +static bool mail_DeleteAttach(int mail_id) { StringBuf buf; int i; @@ -261,86 +253,74 @@ int mail_DeleteAttach(int mail_id) Sql_ShowDebug(sql_handle); StringBuf_Destroy(&buf); - return 0; + return false; } StringBuf_Destroy(&buf); - return 1; + return true; } -int mapif_Mail_getattach(int fd, int char_id, int mail_id) +static void mapif_Mail_getattach(int fd, int char_id, int mail_id) { - struct mail_message *message = (struct mail_message*)aCalloc(sizeof(struct mail_message), 1); + struct mail_message msg; - if( mail_loadmessage(char_id, mail_id, message, 0) ) - { - if( (message->item.nameid < 1 || message->item.amount < 1) && message->zeny < 1 ) - { - aFree(message); - return 0; // No Attachment - } + if( !mail_loadmessage(char_id, mail_id, &msg) ) + return; - if( mail_DeleteAttach(mail_id) ) - { - WFIFOHEAD(fd, sizeof(struct item) + 12); - WFIFOW(fd,0) = 0x384a; - WFIFOW(fd,2) = sizeof(struct item) + 12; - WFIFOL(fd,4) = char_id; - WFIFOL(fd,8) = (message->zeny > 0)?message->zeny:0; - memcpy(WFIFOP(fd,12), &message->item, sizeof(struct item)); - WFIFOSET(fd,WFIFOW(fd,2)); - } - } + if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 ) + return; // No Attachment + + if( !mail_DeleteAttach(mail_id) ) + return; - aFree(message); - return 0; + WFIFOHEAD(fd, sizeof(struct item) + 12); + WFIFOW(fd,0) = 0x384a; + WFIFOW(fd,2) = sizeof(struct item) + 12; + WFIFOL(fd,4) = char_id; + WFIFOL(fd,8) = (msg.zeny > 0)?msg.zeny:0; + memcpy(WFIFOP(fd,12), &msg.item, sizeof(struct item)); + WFIFOSET(fd,WFIFOW(fd,2)); } -int mapif_parse_Mail_getattach(int fd) +static void mapif_parse_Mail_getattach(int fd) { - RFIFOHEAD(fd); mapif_Mail_getattach(fd, RFIFOL(fd,2), RFIFOL(fd,6)); - return 0; } /*========================================== * Delete Mail *------------------------------------------*/ -int mapif_Mail_delete(int fd, int char_id, int mail_id) +static void mapif_Mail_delete(int fd, int char_id, int mail_id) { - short flag = 0; - + bool failed = false; if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) { Sql_ShowDebug(sql_handle); - flag = 1; + failed = true; } WFIFOHEAD(fd,11); WFIFOW(fd,0) = 0x384b; WFIFOL(fd,2) = char_id; WFIFOL(fd,6) = mail_id; - WFIFOW(fd,10) = flag; - WFIFOSET(fd,12); - - return 0; + WFIFOB(fd,10) = failed; + WFIFOSET(fd,11); } -int mapif_parse_Mail_delete(int fd) +static void mapif_parse_Mail_delete(int fd) { - RFIFOHEAD(fd); mapif_Mail_delete(fd, RFIFOL(fd,2), RFIFOL(fd,6)); - return 0; } + /*========================================== * Return Mail *------------------------------------------*/ -int mapif_Mail_return(int fd, int char_id, int mail_id) +static void mapif_Mail_return(int fd, int char_id, int mail_id) { - struct mail_message *msg = (struct mail_message*)aCalloc(sizeof(struct mail_message), 1); + struct mail_message msg; int new_mail = 0; - if( mail_loadmessage(char_id, mail_id, msg, 0) ) + if( mail_loadmessage(char_id, mail_id, &msg) ) { if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) Sql_ShowDebug(sql_handle); @@ -348,97 +328,88 @@ int mapif_Mail_return(int fd, int char_id, int mail_id) { char temp_[MAIL_TITLE_LENGTH]; - swap(msg->send_id, msg->dest_id); - safestrncpy(temp_, msg->send_name, NAME_LENGTH); - safestrncpy(msg->send_name, msg->dest_name, NAME_LENGTH); - safestrncpy(msg->dest_name, temp_, NAME_LENGTH); + // swap sender and receiver + swap(msg.send_id, msg.dest_id); + safestrncpy(temp_, msg.send_name, NAME_LENGTH); + safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH); + safestrncpy(msg.dest_name, temp_, NAME_LENGTH); + + // set reply message title + snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title); + safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH); - snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg->title); - safestrncpy(msg->title, temp_, MAIL_TITLE_LENGTH); - msg->timestamp = (unsigned int)calc_times(); + msg.timestamp = (unsigned int)calc_times(); - new_mail = mail_savemessage(msg); + new_mail = mail_savemessage(&msg); } } - aFree(msg); - WFIFOHEAD(fd,14); WFIFOW(fd,0) = 0x384c; WFIFOL(fd,2) = char_id; WFIFOL(fd,6) = mail_id; WFIFOL(fd,10) = new_mail; WFIFOSET(fd,14); - - return 0; } -int mapif_parse_Mail_return(int fd) +static void mapif_parse_Mail_return(int fd) { - RFIFOHEAD(fd); mapif_Mail_return(fd, RFIFOL(fd,2), RFIFOL(fd,6)); - return 0; } -int mapif_Mail_send(int fd, struct mail_message *msg) +static void mapif_Mail_send(int fd, struct mail_message* msg) { - int len = strlen(msg->title) + 16; + int len = strlen(msg->title); WFIFOHEAD(fd,len); WFIFOW(fd,0) = 0x384d; - WFIFOW(fd,2) = len; + WFIFOW(fd,2) = len + 16; WFIFOL(fd,4) = msg->send_id; WFIFOL(fd,8) = msg->id; WFIFOL(fd,12) = msg->dest_id; - memcpy(WFIFOP(fd,16), msg->title, strlen(msg->title)); - WFIFOSET(fd,len); - - return 0; + safestrncpy((char*)WFIFOP(fd,16), msg->title, len); + WFIFOSET(fd,WFIFOW(fd,2)); } -int mapif_parse_Mail_send(int fd) +static void mapif_parse_Mail_send(int fd) { - struct mail_message *msg; + struct mail_message msg; int mail_id = 0, account_id = 0; if(RFIFOW(fd,2) != 8 + sizeof(struct mail_message)) - return 0; + return; - msg = (struct mail_message*)aCalloc(sizeof(struct mail_message), 1); - memcpy(msg, RFIFOP(fd,8), sizeof(struct mail_message)); + memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message)); account_id = RFIFOL(fd,4); - if( !msg->dest_id ) + if( !msg.dest_id ) { // Try to find the Dest Char by Name char esc_name[NAME_LENGTH*2+1]; - Sql_EscapeStringLen(sql_handle, esc_name, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)); + Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH)); if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) ) Sql_ShowDebug(sql_handle); - else if ( Sql_NumRows(sql_handle) > 0 ) + else + if ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) { char *data; - Sql_NextRow(sql_handle); Sql_GetData(sql_handle, 0, &data, NULL); if (atoi(data) != account_id) - { // Cannot sends mail to char in the same account + { // Cannot send mail to char in the same account Sql_GetData(sql_handle, 1, &data, NULL); - msg->dest_id = atoi(data); + msg.dest_id = atoi(data); } } Sql_FreeResult(sql_handle); } - if( msg->dest_id > 0 ) - mail_id = mail_savemessage(msg); - - msg->id = mail_id; - mapif_Mail_send(fd, msg); + if( msg.dest_id > 0 ) + mail_id = mail_savemessage(&msg); - aFree(msg); - return 0; + msg.id = mail_id; + mapif_Mail_send(fd, &msg); } /*========================================== @@ -462,12 +433,10 @@ int inter_mail_parse_frommap(int fd) int inter_mail_sql_init(void) { - mail_data_pt = (struct mail_data*)aCalloc(sizeof(struct mail_data), 1); return 1; } void inter_mail_sql_final(void) { - if (mail_data_pt) aFree(mail_data_pt); return; } diff --git a/src/char_sql/int_mail.h b/src/char_sql/int_mail.h index 4561e1736..2bd7ca0c5 100644 --- a/src/char_sql/int_mail.h +++ b/src/char_sql/int_mail.h @@ -1,12 +1,12 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef _INT_MAIL_SQL_H_
-#define _INT_MAIL_SQL_H_
-
-int inter_mail_parse_frommap(int fd);
-
-int inter_mail_sql_init(void);
-void inter_mail_sql_final(void);
-
-#endif /* _INT_MAIL_SQL_H_ */
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#ifndef _INT_MAIL_SQL_H_ +#define _INT_MAIL_SQL_H_ + +int inter_mail_parse_frommap(int fd); + +int inter_mail_sql_init(void); +void inter_mail_sql_final(void); + +#endif /* _INT_MAIL_SQL_H_ */ diff --git a/src/common/malloc.h b/src/common/malloc.h index 43eff40f1..f73ff6588 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -28,7 +28,7 @@ // Whether to use Athena's built-in Memory Manager (enabled by default) // To disable just comment the following line #if !defined(DMALLOC) && !defined(BCHECK) - #define USE_MEMMGR + //#define USE_MEMMGR #endif // Whether to enable Memory Manager's logging #define LOG_MEMMGR diff --git a/src/common/mmo.h b/src/common/mmo.h index 2389264d9..171c6c3de 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -132,7 +132,7 @@ struct skill { struct global_reg { char str[32]; - char value[256]; // [zBuffer] + char value[256]; }; //Holds array of global registries, used by the char server and converter. @@ -247,12 +247,11 @@ struct mail_message { char send_name[NAME_LENGTH]; int dest_id; char dest_name[NAME_LENGTH]; - char title[MAIL_TITLE_LENGTH]; char body[MAIL_BODY_LENGTH]; unsigned char read; - unsigned int timestamp; + unsigned int timestamp; // marks when the message was sent int zeny; struct item item; @@ -261,10 +260,8 @@ struct mail_message { struct mail_data { short amount; bool changed, full; - + short unchecked, unread; struct mail_message msg[MAIL_MAX_INBOX]; - - short unchecked, unreaded; }; struct registry { @@ -292,8 +289,6 @@ struct guild_storage { struct item storage_[MAX_GUILD_STORAGE]; }; -struct map_session_data; - struct gm_account { int account_id; int level; @@ -319,6 +314,7 @@ struct party { struct party_member member[MAX_PARTY]; }; +struct map_session_data; struct guild_member { int account_id, char_id; short hair,hair_color,gender,class_,lv; diff --git a/src/common/socket.c b/src/common/socket.c index 79b95c563..7759a67ee 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -452,7 +452,7 @@ int realloc_writefifo(int fd, size_t addition) return 0; // crash prevention for bugs that cause the send queue to fill up in an infinite loop - if( newsize > 1*1024*1024 ) // 1 megabyte is way beyond reasonable + if( newsize > 5*1024*1024 ) // 5 MB is way beyond reasonable { ShowError("realloc_writefifo: session #%d's send buffer was overloaded! Disconnecting...\n", fd); // drop all data (but the space will still be available) diff --git a/src/map/chat.c b/src/map/chat.c index 1a0730b51..67a4dbaee 100644 --- a/src/map/chat.c +++ b/src/map/chat.c @@ -151,15 +151,15 @@ int chat_leavechat(struct map_session_data* sd, bool kicked) return -1; } - leavechar = i; - clif_leavechat(cd, sd, kicked); + pc_setchatid(sd, 0); + cd->users--; + + leavechar = i; for( i = leavechar; i < cd->users; i++ ) cd->usersd[i] = cd->usersd[i+1]; - pc_setchatid(sd, 0); - cd->users--; if( cd->users == 0 && cd->owner->type == BL_PC ) { // Delete empty chatroom diff --git a/src/map/clif.c b/src/map/clif.c index 36a306f0c..3b2fefc1c 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7964,9 +7964,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if(map_flag_gvg(sd->bl.m)) clif_set0199(fd,3); - map_foreachinarea(clif_getareachar, sd->bl.m, - sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, - BL_ALL, sd); + // info about nearby objects + map_foreachinrange(clif_getareachar, &sd->bl, AREA_SIZE, BL_ALL, sd); // pet if(sd->pd) { @@ -11296,11 +11295,12 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd) } #ifndef TXT_ONLY - /*========================================== * MAIL SYSTEM * By Zephyrus - *------------------------------------------ + *==========================================*/ + +/*------------------------------------------ * Opens Mail Window on Client *------------------------------------------*/ void clif_Mail_openmail(int fd) @@ -11310,6 +11310,7 @@ void clif_Mail_openmail(int fd) WFIFOL(fd,2) = 0; WFIFOSET(fd,packet_len(0x260)); } + /*------------------------------------------ * Send Inbox Data to Client *------------------------------------------*/ @@ -11368,7 +11369,12 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) int i, fd = sd->fd; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); - if (i < MAIL_MAX_INBOX) + if( i == MAIL_MAX_INBOX ) + { + ShowWarning("clif_parse_Mail_read: account %d trying to read a message not the inbox.\n", sd->status.account_id); + return; + } + else { struct mail_message *msg = &sd->mail.inbox.msg[i]; struct item *item = &msg->item; @@ -11416,8 +11422,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) WFIFOW(fd,95) = item->card[2]; WFIFOW(fd,97) = item->card[3]; WFIFOB(fd,99) = (unsigned char)msg_len; - memcpy(WFIFOP(fd,100), msg->body, msg_len); - WFIFOB(fd,len - 1) = 0x00; + safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len); WFIFOSET(fd,len); if (!msg->read) { @@ -11426,8 +11431,6 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) clif_parse_Mail_refreshinbox(fd, sd); } } - else - ShowWarning("clif_parse_Mail_read: account %d trying to read a message not the inbox.\n", sd->status.account_id); } void clif_parse_Mail_read(int fd, struct map_session_data *sd) @@ -11445,44 +11448,45 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) nullpo_retv(sd); ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); - if (i < MAIL_MAX_INBOX) + if( i == MAIL_MAX_INBOX ) + return; + + if( sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1) ) + return; + + if( sd->mail.inbox.msg[i].item.nameid > 0 ) { - if (sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1)) + struct item_data *data; + unsigned int weight; + + if ((data = itemdb_search(sd->mail.inbox.msg[i].item.nameid)) == NULL) return; - if (sd->mail.inbox.msg[i].item.nameid > 0) + weight = data->weight * sd->mail.inbox.msg[i].item.amount; + if (weight > sd->max_weight - sd->weight) { - struct item_data *data; - unsigned int weight; - - if ((data = itemdb_search(sd->mail.inbox.msg[i].item.nameid)) == NULL) - return; - - weight = data->weight * sd->mail.inbox.msg[i].item.amount; - if (weight > sd->max_weight - sd->weight) - { - clif_displaymessage(fd, "Attachment to heavy for you..."); - return; - } + clif_displaymessage(fd, "Attachment to heavy for you..."); + return; } + } - sd->mail.inbox.msg[i].zeny = 0; - memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item)); - clif_Mail_read(sd, mail_id); + sd->mail.inbox.msg[i].zeny = 0; + memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item)); + clif_Mail_read(sd, mail_id); - // Send the request for Char Server to delete the attachment - // If it is done, the client will receive it. - intif_Mail_getattach(sd->status.char_id, mail_id); - } + // Send the request for Char Server to delete the attachment + // If it is done, the client will receive it. + intif_Mail_getattach(sd->status.char_id, mail_id); } + /*------------------------------------------ * Delete Message *------------------------------------------*/ -void clif_Mail_delete(struct map_session_data *sd, int mail_id, short flag) +void clif_Mail_delete(struct map_session_data *sd, int mail_id, bool failed) { int fd = sd->fd; - if (!flag) + if( !failed ) { int i; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); @@ -11491,16 +11495,16 @@ void clif_Mail_delete(struct map_session_data *sd, int mail_id, short flag) memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message)); sd->mail.inbox.amount--; } + + if( sd->mail.inbox.full ) + intif_Mail_requestinbox(sd->status.char_id, 1); // Reload the Mail Inbox } WFIFOHEAD(fd, packet_len(0x257)); WFIFOW(fd,0) = 0x257; WFIFOL(fd,2) = mail_id; - WFIFOW(fd,6) = flag; + WFIFOW(fd,6) = failed; WFIFOSET(fd, packet_len(0x257)); - - if( !flag && sd->mail.inbox.full ) - intif_Mail_requestinbox(sd->status.char_id, 1); // Reload the Mail Inbox } void clif_parse_Mail_delete(int fd, struct map_session_data *sd) @@ -11585,7 +11589,8 @@ void clif_Mail_return(struct map_session_data *sd, int mail_id, int new_mail) *------------------------------------------*/ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd) { - int idx = RFIFOW(fd,2), amount = RFIFOL(fd,4); + int idx = RFIFOW(fd,2); + int amount = RFIFOL(fd,4); char flag; nullpo_retv(sd); @@ -11610,9 +11615,9 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) int flag = RFIFOW(fd,2); nullpo_retv(sd); - if (!flag || flag == 1) + if (flag == 0 || flag == 1) mail_removeitem(sd, 0); - if (!flag || flag == 2) + if (flag == 0 || flag == 2) mail_removezeny(sd, 0); } @@ -11627,10 +11632,11 @@ void clif_Mail_send(int fd, unsigned char flag) WFIFOSET(fd,packet_len(0x249)); } +/// S 0248 <packet len>.w <nick>.24B <title>.40B <body len>.B <message>.?B void clif_parse_Mail_send(int fd, struct map_session_data *sd) { struct map_session_data *rd; - struct mail_message *msg; + struct mail_message msg; int body_len; nullpo_retv(sd); @@ -11659,41 +11665,36 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) if (body_len > MAIL_BODY_LENGTH) body_len = MAIL_BODY_LENGTH; - msg = (struct mail_message*)aCalloc(sizeof(struct mail_message), 1); - - if (mail_getattach(sd, msg)) + if( !mail_getattach(sd, &msg) ) { - msg->send_id = sd->status.char_id; - safestrncpy(msg->send_name, sd->status.name, NAME_LENGTH); - - if (rd) { - msg->dest_id = rd->status.char_id; - safestrncpy(msg->dest_name, rd->status.name, NAME_LENGTH); - } else { - msg->dest_id = 0; - safestrncpy(msg->dest_name, RFIFOP(fd,4), NAME_LENGTH); - } + clif_Mail_send(sd->fd, 1); // Fail + mail_removeitem(sd,0); + mail_removezeny(sd,0); + return; + } - memcpy(msg->title, RFIFOP(fd,28), MAIL_TITLE_LENGTH); - - if (body_len) - memcpy(msg->body, RFIFOP(fd,69), body_len); - else - memset(msg->body, 0x00, MAIL_BODY_LENGTH); - - msg->timestamp = (int)mail_calctimes(); - intif_Mail_send(sd->status.account_id, msg); + msg.send_id = sd->status.char_id; + safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH); - sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection + if (rd) { + msg.dest_id = rd->status.char_id; + safestrncpy(msg.dest_name, rd->status.name, NAME_LENGTH); + } else { + msg.dest_id = 0; + safestrncpy(msg.dest_name, (char*)RFIFOP(fd,4), NAME_LENGTH); } + + safestrncpy(msg.title, (char*)RFIFOP(fd,28), MAIL_TITLE_LENGTH); + + if (body_len) + memcpy(msg.body, RFIFOP(fd,69), body_len); else - { - mail_removeitem(sd,0); - mail_removezeny(sd,0); - clif_Mail_send(sd->fd, 1); // Fail - } + memset(msg.body, 0x00, MAIL_BODY_LENGTH); + + msg.timestamp = (int)mail_calctimes(); + intif_Mail_send(sd->status.account_id, &msg); - aFree(msg); + sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection } #endif diff --git a/src/map/clif.h b/src/map/clif.h index 117c7fb24..a3bc84d74 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -386,7 +386,7 @@ int do_init_clif(void); // MAIL SYSTEM void clif_Mail_openmail(int fd); void clif_Mail_read(struct map_session_data *sd, int mail_id); -void clif_Mail_delete(struct map_session_data *sd, int mail_id, short flag); +void clif_Mail_delete(struct map_session_data *sd, int mail_id, bool failed); void clif_Mail_return(struct map_session_data *sd, int mail_id, int new_mail); void clif_Mail_send(int fd, unsigned char flag); void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title); diff --git a/src/map/guild.c b/src/map/guild.c index 1fda18d9f..12577a8fd 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -475,21 +475,23 @@ int guild_request_info(int guild_id) // イベント付き情報要求 int guild_npc_request_info(int guild_id,const char *event) { - struct eventlist *ev; - - if( guild_search(guild_id) ){ - if(event && *event) + if( guild_search(guild_id) ) + { + if( event && *event ) npc_event_do(event); + return 0; } - if(event==NULL || *event==0) - return guild_request_info(guild_id); + if( event && *event ) + { + struct eventlist* ev; + ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1); + memcpy(ev->name,event,strlen(event)); + //The one in the db becomes the next event from this. + ev->next=idb_put(guild_infoevent_db,guild_id,ev); + } - ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1); - memcpy(ev->name,event,strlen(event)); - //The one in the db becomes the next event from this. - ev->next=idb_put(guild_infoevent_db,guild_id,ev); return guild_request_info(guild_id); } @@ -1723,8 +1725,8 @@ int guild_castledataloadack(int castle_id,int index,int value) switch(index){ case 1: gc->guild_id = value; - if (value && guild_search(value)==NULL) //Request guild data which will be required for spawned guardians. [Skotlex] - guild_request_info(value); + if (gc->guild_id && guild_search(gc->guild_id)==NULL) //Request guild data which will be required for spawned guardians. [Skotlex] + guild_request_info(gc->guild_id); break; case 2: gc->economy = value; break; case 3: gc->defense = value; break; @@ -1826,34 +1828,39 @@ int guild_castledatasaveack(int castle_id,int index,int value) int guild_castlealldataload(int len,struct guild_castle *gc) { int i; - int n = (len-4) / sizeof(struct guild_castle), ev = -1; + int n = (len-4) / sizeof(struct guild_castle); + int ev; nullpo_retr(0, gc); //Last owned castle in the list invokes ::OnAgitinit - for(i = 0; i < n; i++) { - if ((gc + i)->guild_id) - ev = i; - } + for( i = n-1; i >= 0 && !(gc[i].guild_id); --i ); + ev = i; // offset of castle or -1 - // 城データ格納とギルド情報要求 - for(i = 0; i < n; i++, gc++) { + // load received castles into memory, one by one + for( i = 0; i < n; i++, gc++ ) + { struct guild_castle *c = guild_castle_search(gc->castle_id); if (!c) { ShowError("guild_castlealldataload Castle id=%d not found.\n", gc->castle_id); continue; } - memcpy(&c->guild_id,&gc->guild_id, - sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c) ); - if( c->guild_id ){ - if(i!=ev) + + // update mapserver castle data with new info + memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c)); + + if( c->guild_id ) + { + if( i != ev ) guild_request_info(c->guild_id); - else + else // last owned one guild_npc_request_info(c->guild_id, "::OnAgitInit"); } } - if (ev == -1) //No castles owned, invoke OnAgitInit as it is. + + if( ev < 0 ) //No castles owned, invoke OnAgitInit as it is. npc_event_doall("OnAgitInit"); + return 0; } diff --git a/src/map/intif.c b/src/map/intif.c index e6fe15242..d6839b180 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -6,6 +6,7 @@ #include "../common/timer.h" #include "../common/nullpo.h" #include "../common/malloc.h" +#include "../common/strlib.h" #include "map.h" #include "battle.h" #include "chrif.h" @@ -33,7 +34,7 @@ static const int packet_len_table[]={ -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 - 9, 9,-1,14, 0, 0, 0, 0, -1, 0,-1,12, 14,-1, 0, 0, //0x3840 + 9, 9,-1,14, 0, 0, 0, 0, -1, 0,-1,11, 14,-1, 0, 0, //0x3840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -259,6 +260,7 @@ int intif_saveregistry(struct map_session_data *sd, int type) { struct global_reg *reg; int count; + int i, p; if (CheckForCharServer()) return -1; @@ -289,18 +291,13 @@ int intif_saveregistry(struct map_session_data *sd, int type) WFIFOL(inter_fd,4)=sd->status.account_id; WFIFOL(inter_fd,8)=sd->status.char_id; WFIFOB(inter_fd,12)=type; - if(count ==0){ - WFIFOW(inter_fd,2)=13; - }else{ - int i,p; - for (p=13,i = 0; i < count; i++) { - if (reg[i].str[0] && reg[i].value != 0) { - p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place. - p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1; - } + for( p = 13, i = 0; i < count; i++ ) { + if (reg[i].str[0] && reg[i].value != 0) { + p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place. + p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1; } - WFIFOW(inter_fd,2)=p; } + WFIFOW(inter_fd,2)=p; WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); return 0; } @@ -853,8 +850,7 @@ int intif_parse_WisMessage(int fd) id=RFIFOL(fd,4); - memcpy(name, RFIFOP(fd,32), NAME_LENGTH); - name[NAME_LENGTH-1] = '\0'; //In case name arrived without it's terminator. [Skotlex] + safestrncpy(name, (char*)RFIFOP(fd,32), NAME_LENGTH); sd = map_nick2sd(name); if(sd == NULL || strcmp(sd->status.name, name) != 0) { //Not found @@ -923,10 +919,8 @@ int mapif_parse_WisToGM(int fd) message = (char *) (mes_len >= 255 ? (char *) aMallocA(mes_len) : mbuf); min_gm_level = (int)RFIFOW(fd,28); - memcpy(Wisp_name, RFIFOP(fd,4), NAME_LENGTH); - Wisp_name[NAME_LENGTH-1] = '\0'; - memcpy(message, RFIFOP(fd,30), mes_len); - message[mes_len-1] = '\0'; + safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH); + safestrncpy(message, (char*)RFIFOP(fd,30), mes_len); // information is sended to all online GM clif_foreachclient(mapif_parse_WisToGM_sub, min_gm_level, Wisp_name, message, mes_len); @@ -1216,70 +1210,59 @@ int intif_parse_GuildBroken(int fd) return 0; } -// ギルド基本情報変更通知 +// basic guild info change notice +// 0x3839 <packet len>.w <guild id>.l <type>.w <data>.?b int intif_parse_GuildBasicInfoChanged(int fd) { - int type, guild_id; - unsigned int dd; - void *data; - struct guild *g; - short dw; - type=RFIFOW(fd,8); - guild_id=RFIFOL(fd,4); - data=RFIFOP(fd,10); - g=guild_search(guild_id); - dw=*((short *)data); - dd=*((unsigned int *)data); - if( g==NULL ) - return 0; - switch(type){ - case GBI_EXP: g->exp=dd; break; - case GBI_GUILDLV: g->guild_lv=dw; break; - case GBI_SKILLPOINT: g->skill_point=dd; break; + //int len = RFIFOW(fd,2) - 10; + int guild_id = RFIFOL(fd,4); + int type = RFIFOW(fd,8); + //void* data = RFIFOP(fd,10); + + struct guild* g = guild_search(guild_id); + if( g == NULL ) + return 0; + + switch(type) { + case GBI_EXP: g->exp = RFIFOL(fd,10); break; + case GBI_GUILDLV: g->guild_lv = RFIFOW(fd,10); break; + case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break; } + return 0; } -// ギルドメンバ情報変更通知 + +// guild member info change notice +// 0x383a <packet len>.w <guild id>.l <account id>.l <char id>.l <type>.w <data>.?b int intif_parse_GuildMemberInfoChanged(int fd) { - int type, guild_id, account_id, char_id, idx, dd; - void* data; - struct guild *g; - type=RFIFOW(fd,16); - guild_id=RFIFOL(fd,4); - account_id=RFIFOL(fd,8); - char_id=RFIFOL(fd,12); - data=RFIFOP(fd,18); - g=guild_search(guild_id); - dd=*((int *)data); - if( g==NULL ) - return 0; - idx=guild_getindex(g,account_id,char_id); - if (idx == -1) - return 0; - switch(type){ - case GMI_POSITION: - g->member[idx].position=dd; - guild_memberposition_changed(g,idx,dd); - break; - case GMI_EXP: - g->member[idx].exp=dd; - break; - case GMI_HAIR: - g->member[idx].hair=dd; - break; - case GMI_HAIR_COLOR: - g->member[idx].hair_color=dd; - break; - case GMI_GENDER: - g->member[idx].gender=dd; - break; - case GMI_CLASS: - g->member[idx].class_=dd; - break; - case GMI_LEVEL: - g->member[idx].lv=dd; - break; + //int len = RFIFOW(fd,2) - 18; + int guild_id = RFIFOL(fd,4); + int account_id = RFIFOL(fd,8); + int char_id = RFIFOL(fd,12); + int type = RFIFOW(fd,16); + void* data = RFIFOP(fd,18); + int dd = *((int *)data); + + struct guild* g; + int idx; + + g = guild_search(guild_id); + if( g == NULL ) + return 0; + + idx = guild_getindex(g,account_id,char_id); + if( idx == -1 ) + return 0; + + switch( type ) { + case GMI_POSITION: g->member[idx].position = dd; guild_memberposition_changed(g,idx,dd); break; + case GMI_EXP: g->member[idx].exp = dd; break; + case GMI_HAIR: g->member[idx].hair = dd; break; + case GMI_HAIR_COLOR: g->member[idx].hair_color = dd; break; + case GMI_GENDER: g->member[idx].gender = dd; break; + case GMI_CLASS: g->member[idx].class_ = dd; break; + case GMI_LEVEL: g->member[idx].lv = dd; break; } return 0; } @@ -1303,8 +1286,7 @@ int intif_parse_GuildSkillUp(int fd) // ギルド同盟/敵対通知 int intif_parse_GuildAlliance(int fd) { - guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14), - RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43)); + guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43)); return 0; } // ギルド告知変更通知 @@ -1460,15 +1442,16 @@ int intif_parse_DeleteHomunculusOk(int fd) return 0; } +#ifndef TXT_ONLY /*========================================== * MAIL SYSTEM * By Zephyrus - *------------------------------------------ + *==========================================*/ + +/*------------------------------------------ * Inbox Request * flag: 0 Update Inbox | 1 OpenMail *------------------------------------------*/ -#ifndef TXT_ONLY - int intif_Mail_requestinbox(int char_id, unsigned char flag) { if (CheckForCharServer()) @@ -1488,7 +1471,7 @@ int intif_parse_Mail_inboxreceived(int fd) struct map_session_data *sd; unsigned char flag = RFIFOB(fd,8); - sd = map_charid2sd( RFIFOL(fd,4) ); + sd = map_charid2sd(RFIFOL(fd,4)); if (sd == NULL) { @@ -1507,7 +1490,7 @@ int intif_parse_Mail_inboxreceived(int fd) return 1; } - memset(&sd->mail.inbox, 0, sizeof(struct mail_data)); + //FIXME: this operation is not safe [ultramage] memcpy(&sd->mail.inbox, RFIFOP(fd,9), sizeof(struct mail_data)); if (flag) @@ -1515,7 +1498,7 @@ int intif_parse_Mail_inboxreceived(int fd) else { char output[128]; - sprintf(output, "You have %d new emails (%d unreaded)", sd->mail.inbox.unchecked, sd->mail.inbox.unreaded + sd->mail.inbox.unchecked); + sprintf(output, "You have %d new emails (%d unread)", sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked); clif_disp_onlyself(sd, output, strlen(output)); } return 0; @@ -1611,21 +1594,22 @@ int intif_Mail_delete(int char_id, int mail_id) int intif_parse_Mail_delete(int fd) { - struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2)); + int char_id = RFIFOL(fd,2); int mail_id = RFIFOL(fd,6); - short flag = RFIFOW(fd,10); + bool failed = RFIFOB(fd,10); + struct map_session_data *sd = map_charid2sd(char_id); if (sd == NULL) { if (battle_config.error_log) - ShowError("intif_parse_Mail_delete: char not found %d\n",RFIFOL(fd,2)); + ShowError("intif_parse_Mail_delete: char not found %d\n", char_id); return 1; } if (sd->state.finalsave) return 1; - clif_Mail_delete(sd, mail_id, flag); + clif_Mail_delete(sd, mail_id, failed); return 0; } /*------------------------------------------ diff --git a/src/map/npc.c b/src/map/npc.c index b2de0af2a..87ceb8afb 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -337,19 +337,16 @@ int npc_event_do_clock(int tid, unsigned int tick, int id, int data) memcpy(&ev_tm_b,t,sizeof(ev_tm_b)); return c; } + /*========================================== * OnInitイベント実行(&時計イベント開始) *------------------------------------------*/ -int npc_event_do_oninit(void) +void npc_event_do_oninit(void) { -// int c = npc_event_doall("OnInit"); - ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '" - CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit")); - - add_timer_interval(gettick()+100, - npc_event_do_clock,0,0,1000); + int count = npc_event_doall("OnInit"); + ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs."CL_CLL"\n", count); - return 0; + add_timer_interval(gettick()+100,npc_event_do_clock,0,0,1000); } /*========================================== diff --git a/src/map/npc.h b/src/map/npc.h index 7293b4a7c..908ca3382 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -69,7 +69,7 @@ void npc_delsrcfile(const char* name); void npc_parsesrcfile(const char* filepath); int do_final_npc(void); int do_init_npc(void); -int npc_event_do_oninit(void); +void npc_event_do_oninit(void); int npc_do_ontimer(int npc_id, int option); int npc_event_doall(const char* name); diff --git a/src/map/skill.c b/src/map/skill.c index bd58f6a9b..130087e33 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -7399,15 +7399,17 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns int count=0; int x = bl->x, y = bl->y; //If target isn't knocked back it should hit every 20ms [Playtester] - while (count++ < SKILLUNITTIMER_INTERVAL/sg->interval && x == bl->x && y == bl->y && !status_isdead(bl)){ - if (bl->type==BL_PC) + while( count++ < SKILLUNITTIMER_INTERVAL/sg->interval && x == bl->x && y == bl->y && !status_isdead(bl) ) + { + if( bl->type == BL_PC ) status_zap(bl, 0, 15); //Only damage SP [Skotlex] - else if (!status_charge(ss, 0, 2)){ //should end when out of sp. - sg->limit=DIFF_TICK(tick,sg->tick); + else // mobs + if( status_charge(ss, 0, 2) ) // costs 2 SP per hit + skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*20,0); + else { //should end when out of sp. + sg->limit = DIFF_TICK(tick,sg->tick); break; } - else - skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*20,0); } } break; @@ -8020,8 +8022,7 @@ int skill_check_pc_partner (struct map_session_data *sd, short skill_id, short* //Else: new search for partners. c = 0; memset (p_sd, 0, sizeof(p_sd)); - i = map_foreachinrange(skill_check_condition_char_sub, &sd->bl, - range, BL_PC, &sd->bl, &c, &p_sd, skill_id); + i = map_foreachinrange(skill_check_condition_char_sub, &sd->bl, range, BL_PC, &sd->bl, &c, &p_sd, skill_id); if (skill_id != PR_BENEDICTIO) //Apply the average lv to encore skills. *skill_lv = (i+(*skill_lv))/(c+1); //I know c should be one, but this shows how it could be used for the average of n partners. diff --git a/vcproj-6/char-server_sql.dsp b/vcproj-6/char-server_sql.dsp index f84332a7b..2b11e80d7 100644 --- a/vcproj-6/char-server_sql.dsp +++ b/vcproj-6/char-server_sql.dsp @@ -211,6 +211,14 @@ SOURCE=..\src\char_sql\int_homun.h # End Source File
# Begin Source File
+SOURCE=..\src\char_sql\int_mail.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\char_sql\int_mail.h
+# End Source File
+# Begin Source File
+
SOURCE=..\src\char_sql\int_party.c
# End Source File
# Begin Source File
diff --git a/vcproj-7.1/char-server_sql.vcproj b/vcproj-7.1/char-server_sql.vcproj index ec46bb71c..f0ed1a41f 100644 --- a/vcproj-7.1/char-server_sql.vcproj +++ b/vcproj-7.1/char-server_sql.vcproj @@ -162,6 +162,12 @@ RelativePath="..\src\char_sql\int_homun.h"> </File> <File + RelativePath="..\src\char_sql\int_mail.c"> + </File> + <File + RelativePath="..\src\char_sql\int_mail.h"> + </File> + <File RelativePath="..\src\char_sql\int_party.c"> </File> <File |