* Cleaned up some messy guild code (more to come)
* Cleaned up the mail code, no more pointless dynamic allocation * Added upgrade_svn11548.sql to convert the mail table to new format * Updated vs7 and vs6 project files * Increased the max. send buffer size to 5M since 1M is not enough * Please complain if something stops working ^^; git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11571 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
895ee4a0ad
commit
d091f1cf05
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
29
sql-files/upgrade_svn11548.sql
Normal file
29
sql-files/upgrade_svn11548.sql
Normal file
@ -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`);
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
char* data;
|
||||
|
||||
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++)
|
||||
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
|
||||
|
||||
aFree(message);
|
||||
return 0;
|
||||
if( !mail_DeleteAttach(mail_id) )
|
||||
return;
|
||||
|
||||
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);
|
||||
|
||||
snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg->title);
|
||||
safestrncpy(msg->title, temp_, MAIL_TITLE_LENGTH);
|
||||
msg->timestamp = (unsigned int)calc_times();
|
||||
// set reply message title
|
||||
snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title);
|
||||
safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH);
|
||||
|
||||
new_mail = mail_savemessage(msg);
|
||||
msg.timestamp = (unsigned int)calc_times();
|
||||
|
||||
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);
|
||||
if( msg.dest_id > 0 )
|
||||
mail_id = mail_savemessage(&msg);
|
||||
|
||||
msg->id = mail_id;
|
||||
mapif_Mail_send(fd, 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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
147
src/map/clif.c
147
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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* 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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection
|
||||
}
|
||||
else
|
||||
if( !mail_getattach(sd, &msg) )
|
||||
{
|
||||
clif_Mail_send(sd->fd, 1); // Fail
|
||||
mail_removeitem(sd,0);
|
||||
mail_removezeny(sd,0);
|
||||
clif_Mail_send(sd->fd, 1); // Fail
|
||||
return;
|
||||
}
|
||||
|
||||
aFree(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, (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
|
||||
memset(msg.body, 0x00, MAIL_BODY_LENGTH);
|
||||
|
||||
msg.timestamp = (int)mail_calctimes();
|
||||
intif_Mail_send(sd->status.account_id, &msg);
|
||||
|
||||
sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
@ -475,21 +475,23 @@ int guild_request_info(int guild_id)
|
||||
// ƒCƒxƒ“ƒg•t‚«<E2809A>î•ñ—v‹<76>
|
||||
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;
|
||||
}
|
||||
|
||||
|
150
src/map/intif.c
150
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 )
|
||||
//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=dd; break;
|
||||
case GBI_GUILDLV: g->guild_lv=dw; break;
|
||||
case GBI_SKILLPOINT: g->skill_point=dd; break;
|
||||
|
||||
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 )
|
||||
//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)
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
/*------------------------------------------
|
||||
|
@ -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"));
|
||||
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);
|
||||
|
||||
add_timer_interval(gettick()+100,
|
||||
npc_event_do_clock,0,0,1000);
|
||||
|
||||
return 0;
|
||||
add_timer_interval(gettick()+100,npc_event_do_clock,0,0,1000);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -161,6 +161,12 @@
|
||||
<File
|
||||
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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user