* Merged changes from trunk [14827:14894/trunk].

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/renewal@14895 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
ai4rei 2011-07-10 06:17:06 +00:00
parent efc8511dea
commit f0d5c981e1
149 changed files with 6222 additions and 1556 deletions

54
3rdparty/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,54 @@
# macro to configure the use of local or system version of a package
# Uses:
# HAVE_LOCAL_${name} - is local version available?
# ${name}_LOCAL_LIBRARIES - libraries of the local version
# ${name}_LOCAL_INCLUDE_DIRS - include directories of the local version
# HAVE_SYSTEM_${name} - is system version available?
# ${name}_SYSTEM_LIBRARIES - libraries of the system version
# ${name}_SYSTEM_INCLUDE_DIRS - include directories of the system version
# Generates:
# WITH_LOCAL_${name} - use the local version of the package (only when local is available)
# WITH_${name} - use this package
# ${name}_LIBRARIES - libraries
# ${name}_INCLUDE_DIRS - include directories
macro( CONFIGURE_WITH_LOCAL_OR_SYSTEM name )
unset( ${name}_LIBRARIES CACHE )
unset( ${name}_INCLUDE_DIRS CACHE )
if( HAVE_LOCAL_${name} )
set( WITH_LOCAL_${name} ON
CACHE BOOL "use local version of ${name}" )
else()
unset( WITH_LOCAL_${name} CACHE )
endif()
if( WITH_LOCAL_${name} )
message( STATUS "Configuring for local ${name}" )
set( ${name}_LIBRARIES ${${name}_LOCAL_LIBRARIES} )
set( ${name}_INCLUDE_DIRS ${${name}_LOCAL_INCLUDE_DIRS} )
message( STATUS "Configuring for local ${name} - done" )
elseif( HAVE_SYSTEM_${name} )
message( STATUS "Configuring for system ${name}" )
set( ${name}_LIBRARIES ${${name}_SYSTEM_LIBRARIES} )
set( ${name}_INCLUDE_DIRS ${${name}_SYSTEM_INCLUDE_DIRS} )
message( STATUS "Configuring for system ${name} - done" )
endif()
if( WITH_LOCAL_${name} OR HAVE_SYSTEM_${name} )
set( WITH_${name} ON
CACHE BOOL "use ${name}" )
else()
unset( WITH_${name} CACHE )
endif()
set( ${name}_LIBRARIES ${${name}_LIBRARIES}
CACHE PATH "${name} libraries" )
set( ${name}_INCLUDE_DIRS ${${name}_INCLUDE_DIRS}
CACHE PATH "${name} include directories" )
mark_as_advanced( ${name}_LIBRARIES )
mark_as_advanced( ${name}_INCLUDE_DIRS )
endmacro( CONFIGURE_WITH_LOCAL_OR_SYSTEM )
add_subdirectory( msinttypes )
add_subdirectory( mt19937ar )
add_subdirectory( mysql )
add_subdirectory( pcre )
add_subdirectory( zlib )

8
3rdparty/msinttypes/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,8 @@
if( WIN32 )
find_path( MSINTTYPES_INCLUDE_DIRS "inttypes.h"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/include"
NO_DEFAULT_PATH )
mark_as_advanced( MSINTTYPES_INCLUDE_DIRS )
set( GLOBAL_INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MSINTTYPES_INCLUDE_DIRS} CACHE INTERNAL "" )
endif()

16
3rdparty/mt19937ar/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,16 @@
find_path( MT19937AR_INCLUDE_DIRS "mt19937ar.h"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}"
NO_DEFAULT_PATH )
find_path( MT19937AR_SOURCE_DIR "mt19937ar.c"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}"
NO_DEFAULT_PATH )
mark_as_advanced( MT19937AR_INCLUDE_DIRS )
mark_as_advanced( MT19937AR_SOURCE_DIR )
set( MT19937AR_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/mt19937ar.h"
CACHE INTERNAL "mt19937ar headers" )
set( MT19937AR_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/mt19937ar.c"
CACHE INTERNAL "mt19937ar sources" )

24
3rdparty/mt19937ar/Makefile.in vendored Normal file
View File

@ -0,0 +1,24 @@
MT19937AR_OBJ = mt19937ar.o
MT19937AR_H = mt19937ar.h
@SET_MAKE@
#####################################################################
.PHONY : all clean help
all: $(MT19937AR_OBJ)
clean:
rm -rf *.o
help:
@echo "possible targets are 'all' 'clean' 'help'"
@echo "'all' - builds $(MT19937AR_OBJ)"
@echo "'clean' - deletes $(MT19937AR_OBJ)"
@echo "'help' - outputs this message"
#####################################################################
%.o: %.c $(MT19937AR_H)
@CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<

175
3rdparty/mt19937ar/mt19937ar.c vendored Normal file
View File

@ -0,0 +1,175 @@
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Copyright (C) 2005, Mutsuo Saito,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
#include <stdio.h>
#include "mt19937ar.h"
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
static unsigned long mt[N]; /* the array for the state vector */
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
/* initializes mt[N] with a seed */
void init_genrand(unsigned long s)
{
mt[0]= s & 0xffffffffUL;
for (mti=1; mti<N; mti++) {
mt[mti] =
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
mt[mti] &= 0xffffffffUL;
/* for >32 bit machines */
}
}
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
void init_by_array(unsigned long init_key[], int key_length)
{
int i, j, k;
init_genrand(19650218UL);
i=1; j=0;
k = (N>key_length ? N : key_length);
for (; k; k--) {
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+ init_key[j] + j; /* non linear */
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
i++; j++;
if (i>=N) { mt[0] = mt[N-1]; i=1; }
if (j>=key_length) j=0;
}
for (k=N-1; k; k--) {
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
- i; /* non linear */
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
i++;
if (i>=N) { mt[0] = mt[N-1]; i=1; }
}
mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
}
/* generates a random number on [0,0xffffffff]-interval */
unsigned long genrand_int32(void)
{
unsigned long y;
static unsigned long mag01[2]={0x0UL, MATRIX_A};
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (mti >= N) { /* generate N words at one time */
int kk;
if (mti == N+1) /* if init_genrand() has not been called, */
init_genrand(5489UL); /* a default initial seed is used */
for (kk=0;kk<N-M;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
}
for (;kk<N-1;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
mti = 0;
}
y = mt[mti++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}
/* generates a random number on [0,0x7fffffff]-interval */
long genrand_int31(void)
{
return (long)(genrand_int32()>>1);
}
/* generates a random number on [0,1]-real-interval */
double genrand_real1(void)
{
return genrand_int32()*(1.0/4294967295.0);
/* divided by 2^32-1 */
}
/* generates a random number on [0,1)-real-interval */
double genrand_real2(void)
{
return genrand_int32()*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on (0,1)-real-interval */
double genrand_real3(void)
{
return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on [0,1) with 53-bit resolution*/
double genrand_res53(void)
{
unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */

72
3rdparty/mt19937ar/mt19937ar.h vendored Normal file
View File

@ -0,0 +1,72 @@
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Copyright (C) 2005, Mutsuo Saito
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
/* initializes mt[N] with a seed */
void init_genrand(unsigned long s);
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
void init_by_array(unsigned long init_key[], int key_length);
/* generates a random number on [0,0xffffffff]-interval */
unsigned long genrand_int32(void);
/* generates a random number on [0,0x7fffffff]-interval */
long genrand_int31(void);
/* These real versions are due to Isaku Wada, 2002/01/09 added */
/* generates a random number on [0,1]-real-interval */
double genrand_real1(void);
/* generates a random number on [0,1)-real-interval */
double genrand_real2(void);
/* generates a random number on (0,1)-real-interval */
double genrand_real3(void);
/* generates a random number on [0,1) with 53-bit resolution*/
double genrand_res53(void);

403
3rdparty/mt19937ar/mt19937ar.out vendored Normal file
View File

@ -0,0 +1,403 @@
1000 outputs of genrand_int32()
1067595299 955945823 477289528 4107218783 4228976476
3344332714 3355579695 227628506 810200273 2591290167
2560260675 3242736208 646746669 1479517882 4245472273
1143372638 3863670494 3221021970 1773610557 1138697238
1421897700 1269916527 2859934041 1764463362 3874892047
3965319921 72549643 2383988930 2600218693 3237492380
2792901476 725331109 605841842 271258942 715137098
3297999536 1322965544 4229579109 1395091102 3735697720
2101727825 3730287744 2950434330 1661921839 2895579582
2370511479 1004092106 2247096681 2111242379 3237345263
4082424759 219785033 2454039889 3709582971 835606218
2411949883 2735205030 756421180 2175209704 1873865952
2762534237 4161807854 3351099340 181129879 3269891896
776029799 2218161979 3001745796 1866825872 2133627728
34862734 1191934573 3102311354 2916517763 1012402762
2184831317 4257399449 2899497138 3818095062 3030756734
1282161629 420003642 2326421477 2741455717 1278020671
3744179621 271777016 2626330018 2560563991 3055977700
4233527566 1228397661 3595579322 1077915006 2395931898
1851927286 3013683506 1999971931 3006888962 1049781534
1488758959 3491776230 104418065 2448267297 3075614115
3872332600 891912190 3936547759 2269180963 2633455084
1047636807 2604612377 2709305729 1952216715 207593580
2849898034 670771757 2210471108 467711165 263046873
3569667915 1042291111 3863517079 1464270005 2758321352
3790799816 2301278724 3106281430 7974801 2792461636
555991332 621766759 1322453093 853629228 686962251
1455120532 957753161 1802033300 1021534190 3486047311
1902128914 3701138056 4176424663 1795608698 560858864
3737752754 3141170998 1553553385 3367807274 711546358
2475125503 262969859 251416325 2980076994 1806565895
969527843 3529327173 2736343040 2987196734 1649016367
2206175811 3048174801 3662503553 3138851612 2660143804
1663017612 1816683231 411916003 3887461314 2347044079
1015311755 1203592432 2170947766 2569420716 813872093
1105387678 1431142475 220570551 4243632715 4179591855
2607469131 3090613241 282341803 1734241730 1391822177
1001254810 827927915 1886687171 3935097347 2631788714
3905163266 110554195 2447955646 3717202975 3304793075
3739614479 3059127468 953919171 2590123714 1132511021
3795593679 2788030429 982155079 3472349556 859942552
2681007391 2299624053 647443547 233600422 608168955
3689327453 1849778220 1608438222 3968158357 2692977776
2851872572 246750393 3582818628 3329652309 4036366910
1012970930 950780808 3959768744 2538550045 191422718
2658142375 3276369011 2927737484 1234200027 1920815603
3536074689 1535612501 2184142071 3276955054 428488088
2378411984 4059769550 3913744741 2732139246 64369859
3755670074 842839565 2819894466 2414718973 1010060670
1839715346 2410311136 152774329 3485009480 4102101512
2852724304 879944024 1785007662 2748284463 1354768064
3267784736 2269127717 3001240761 3179796763 895723219
865924942 4291570937 89355264 1471026971 4114180745
3201939751 2867476999 2460866060 3603874571 2238880432
3308416168 2072246611 2755653839 3773737248 1709066580
4282731467 2746170170 2832568330 433439009 3175778732
26248366 2551382801 183214346 3893339516 1928168445
1337157619 3429096554 3275170900 1782047316 4264403756
1876594403 4289659572 3223834894 1728705513 4068244734
2867840287 1147798696 302879820 1730407747 1923824407
1180597908 1569786639 198796327 560793173 2107345620
2705990316 3448772106 3678374155 758635715 884524671
486356516 1774865603 3881226226 2635213607 1181121587
1508809820 3178988241 1594193633 1235154121 326117244
2304031425 937054774 2687415945 3192389340 2003740439
1823766188 2759543402 10067710 1533252662 4132494984
82378136 420615890 3467563163 541562091 3535949864
2277319197 3330822853 3215654174 4113831979 4204996991
2162248333 3255093522 2219088909 2978279037 255818579
2859348628 3097280311 2569721123 1861951120 2907080079
2719467166 998319094 2521935127 2404125338 259456032
2086860995 1839848496 1893547357 2527997525 1489393124
2860855349 76448234 2264934035 744914583 2586791259
1385380501 66529922 1819103258 1899300332 2098173828
1793831094 276463159 360132945 4178212058 595015228
177071838 2800080290 1573557746 1548998935 378454223
1460534296 1116274283 3112385063 3709761796 827999348
3580042847 1913901014 614021289 4278528023 1905177404
45407939 3298183234 1184848810 3644926330 3923635459
1627046213 3677876759 969772772 1160524753 1522441192
452369933 1527502551 832490847 1003299676 1071381111
2891255476 973747308 4086897108 1847554542 3895651598
2227820339 1621250941 2881344691 3583565821 3510404498
849362119 862871471 797858058 2867774932 2821282612
3272403146 3997979905 209178708 1805135652 6783381
2823361423 792580494 4263749770 776439581 3798193823
2853444094 2729507474 1071873341 1329010206 1289336450
3327680758 2011491779 80157208 922428856 1158943220
1667230961 2461022820 2608845159 387516115 3345351910
1495629111 4098154157 3156649613 3525698599 4134908037
446713264 2137537399 3617403512 813966752 1157943946
3734692965 1680301658 3180398473 3509854711 2228114612
1008102291 486805123 863791847 3189125290 1050308116
3777341526 4291726501 844061465 1347461791 2826481581
745465012 2055805750 4260209475 2386693097 2980646741
447229436 2077782664 1232942813 4023002732 1399011509
3140569849 2579909222 3794857471 900758066 2887199683
1720257997 3367494931 2668921229 955539029 3818726432
1105704962 3889207255 2277369307 2746484505 1761846513
2413916784 2685127085 4240257943 1166726899 4215215715
3082092067 3960461946 1663304043 2087473241 4162589986
2507310778 1579665506 767234210 970676017 492207530
1441679602 1314785090 3262202570 3417091742 1561989210
3011406780 1146609202 3262321040 1374872171 1634688712
1280458888 2230023982 419323804 3262899800 39783310
1641619040 1700368658 2207946628 2571300939 2424079766
780290914 2715195096 3390957695 163151474 2309534542
1860018424 555755123 280320104 1604831083 2713022383
1728987441 3639955502 623065489 3828630947 4275479050
3516347383 2343951195 2430677756 635534992 3868699749
808442435 3070644069 4282166003 2093181383 2023555632
1568662086 3422372620 4134522350 3016979543 3259320234
2888030729 3185253876 4258779643 1267304371 1022517473
815943045 929020012 2995251018 3371283296 3608029049
2018485115 122123397 2810669150 1411365618 1238391329
1186786476 3155969091 2242941310 1765554882 279121160
4279838515 1641578514 3796324015 13351065 103516986
1609694427 551411743 2493771609 1316337047 3932650856
4189700203 463397996 2937735066 1855616529 2626847990
55091862 3823351211 753448970 4045045500 1274127772
1124182256 92039808 2126345552 425973257 386287896
2589870191 1987762798 4084826973 2172456685 3366583455
3602966653 2378803535 2901764433 3716929006 3710159000
2653449155 3469742630 3096444476 3932564653 2595257433
318974657 3146202484 853571438 144400272 3768408841
782634401 2161109003 570039522 1886241521 14249488
2230804228 1604941699 3928713335 3921942509 2155806892
134366254 430507376 1924011722 276713377 196481886
3614810992 1610021185 1785757066 851346168 3761148643
2918835642 3364422385 3012284466 3735958851 2643153892
3778608231 1164289832 205853021 2876112231 3503398282
3078397001 3472037921 1748894853 2740861475 316056182
1660426908 168885906 956005527 3984354789 566521563
1001109523 1216710575 2952284757 3834433081 3842608301
2467352408 3974441264 3256601745 1409353924 1329904859
2307560293 3125217879 3622920184 3832785684 3882365951
2308537115 2659155028 1450441945 3532257603 3186324194
1225603425 1124246549 175808705 3009142319 2796710159
3651990107 160762750 1902254979 1698648476 1134980669
497144426 3302689335 4057485630 3603530763 4087252587
427812652 286876201 823134128 1627554964 3745564327
2589226092 4202024494 62878473 3275585894 3987124064
2791777159 1916869511 2585861905 1375038919 1403421920
60249114 3811870450 3021498009 2612993202 528933105
2757361321 3341402964 2621861700 273128190 4015252178
3094781002 1621621288 2337611177 1796718448 1258965619
4241913140 2138560392 3022190223 4174180924 450094611
3274724580 617150026 2704660665 1469700689 1341616587
356715071 1188789960 2278869135 1766569160 2795896635
57824704 2893496380 1235723989 1630694347 3927960522
428891364 1814070806 2287999787 4125941184 3968103889
3548724050 1025597707 1404281500 2002212197 92429143
2313943944 2403086080 3006180634 3561981764 1671860914
1768520622 1803542985 844848113 3006139921 1410888995
1157749833 2125704913 1789979528 1799263423 741157179
2405862309 767040434 2655241390 3663420179 2172009096
2511931187 1680542666 231857466 1154981000 157168255
1454112128 3505872099 1929775046 2309422350 2143329496
2960716902 407610648 2938108129 2581749599 538837155
2342628867 430543915 740188568 1937713272 3315215132
2085587024 4030765687 766054429 3517641839 689721775
1294158986 1753287754 4202601348 1974852792 33459103
3568087535 3144677435 1686130825 4134943013 3005738435
3599293386 426570142 754104406 3660892564 1964545167
829466833 821587464 1746693036 1006492428 1595312919
1256599985 1024482560 1897312280 2902903201 691790057
1037515867 3176831208 1968401055 2173506824 1089055278
1748401123 2941380082 968412354 1818753861 2973200866
3875951774 1119354008 3988604139 1647155589 2232450826
3486058011 3655784043 3759258462 847163678 1082052057
989516446 2871541755 3196311070 3929963078 658187585
3664944641 2175149170 2203709147 2756014689 2456473919
3890267390 1293787864 2830347984 3059280931 4158802520
1561677400 2586570938 783570352 1355506163 31495586
3789437343 3340549429 2092501630 896419368 671715824
3530450081 3603554138 1055991716 3442308219 1499434728
3130288473 3639507000 17769680 2259741420 487032199
4227143402 3693771256 1880482820 3924810796 381462353
4017855991 2452034943 2736680833 2209866385 2128986379
437874044 595759426 641721026 1636065708 3899136933
629879088 3591174506 351984326 2638783544 2348444281
2341604660 2123933692 143443325 1525942256 364660499
599149312 939093251 1523003209 106601097 376589484
1346282236 1297387043 764598052 3741218111 933457002
1886424424 3219631016 525405256 3014235619 323149677
2038881721 4100129043 2851715101 2984028078 1888574695
2014194741 3515193880 4180573530 3461824363 2641995497
3179230245 2902294983 2217320456 4040852155 1784656905
3311906931 87498458 2752971818 2635474297 2831215366
3682231106 2920043893 3772929704 2816374944 309949752
2383758854 154870719 385111597 1191604312 1840700563
872191186 2925548701 1310412747 2102066999 1504727249
3574298750 1191230036 3330575266 3180292097 3539347721
681369118 3305125752 3648233597 950049240 4173257693
1760124957 512151405 681175196 580563018 1169662867
4015033554 2687781101 699691603 2673494188 1137221356
123599888 472658308 1053598179 1012713758 3481064843
3759461013 3981457956 3830587662 1877191791 3650996736
988064871 3515461600 4089077232 2225147448 1249609188
2643151863 3896204135 2416995901 1397735321 3460025646
1000 outputs of genrand_real2()
0.76275443 0.99000644 0.98670464 0.10143112 0.27933125
0.69867227 0.94218740 0.03427201 0.78842173 0.28180608
0.92179002 0.20785655 0.54534773 0.69644020 0.38107718
0.23978165 0.65286910 0.07514568 0.22765211 0.94872929
0.74557914 0.62664415 0.54708246 0.90959343 0.42043116
0.86334511 0.19189126 0.14718544 0.70259889 0.63426346
0.77408121 0.04531601 0.04605807 0.88595519 0.69398270
0.05377184 0.61711170 0.05565708 0.10133577 0.41500776
0.91810699 0.22320679 0.23353705 0.92871862 0.98897234
0.19786706 0.80558809 0.06961067 0.55840445 0.90479405
0.63288060 0.95009721 0.54948447 0.20645042 0.45000959
0.87050869 0.70806991 0.19406895 0.79286390 0.49332866
0.78483914 0.75145146 0.12341941 0.42030252 0.16728160
0.59906494 0.37575460 0.97815160 0.39815952 0.43595080
0.04952478 0.33917805 0.76509902 0.61034321 0.90654701
0.92915732 0.85365931 0.18812377 0.65913428 0.28814566
0.59476081 0.27835931 0.60722542 0.68310435 0.69387186
0.03699800 0.65897714 0.17527003 0.02889304 0.86777366
0.12352068 0.91439461 0.32022990 0.44445731 0.34903686
0.74639273 0.65918367 0.92492794 0.31872642 0.77749724
0.85413832 0.76385624 0.32744211 0.91326300 0.27458185
0.22190155 0.19865383 0.31227402 0.85321225 0.84243342
0.78544200 0.71854080 0.92503892 0.82703064 0.88306297
0.47284073 0.70059042 0.48003761 0.38671694 0.60465770
0.41747204 0.47163243 0.72750808 0.65830223 0.10955369
0.64215401 0.23456345 0.95944940 0.72822249 0.40888451
0.69980355 0.26677428 0.57333635 0.39791582 0.85377858
0.76962816 0.72004885 0.90903087 0.51376506 0.37732665
0.12691640 0.71249738 0.81217908 0.37037313 0.32772374
0.14238259 0.05614811 0.74363008 0.39773267 0.94859135
0.31452454 0.11730313 0.62962618 0.33334237 0.45547255
0.10089665 0.56550662 0.60539371 0.16027624 0.13245301
0.60959939 0.04671662 0.99356286 0.57660859 0.40269560
0.45274629 0.06699735 0.85064246 0.87742744 0.54508392
0.87242982 0.29321385 0.67660627 0.68230715 0.79052073
0.48592054 0.25186266 0.93769755 0.28565487 0.47219067
0.99054882 0.13155240 0.47110470 0.98556600 0.84397623
0.12875246 0.90953202 0.49129015 0.23792727 0.79481194
0.44337770 0.96564297 0.67749118 0.55684872 0.27286897
0.79538393 0.61965356 0.22487929 0.02226018 0.49248200
0.42247006 0.91797788 0.99250134 0.23449967 0.52531508
0.10246337 0.78685622 0.34310922 0.89892996 0.40454552
0.68608407 0.30752487 0.83601319 0.54956031 0.63777550
0.82199797 0.24890696 0.48801123 0.48661910 0.51223987
0.32969635 0.31075073 0.21393155 0.73453207 0.15565705
0.58584522 0.28976728 0.97621478 0.61498701 0.23891470
0.28518540 0.46809591 0.18371914 0.37597910 0.13492176
0.66849449 0.82811466 0.56240330 0.37548956 0.27562998
0.27521910 0.74096121 0.77176757 0.13748143 0.99747138
0.92504502 0.09175241 0.21389176 0.21766512 0.31183245
0.23271221 0.21207367 0.57903312 0.77523344 0.13242613
0.31037988 0.01204835 0.71652949 0.84487594 0.14982178
0.57423142 0.45677888 0.48420169 0.53465428 0.52667473
0.46880526 0.49849733 0.05670710 0.79022476 0.03872047
0.21697212 0.20443086 0.28949326 0.81678186 0.87629474
0.92297064 0.27373097 0.84625273 0.51505586 0.00582792
0.33295971 0.91848412 0.92537226 0.91760033 0.07541125
0.71745848 0.61158698 0.00941650 0.03135554 0.71527471
0.24821915 0.63636652 0.86159918 0.26450229 0.60160194
0.35557725 0.24477500 0.07186456 0.51757096 0.62120362
0.97981062 0.69954667 0.21065616 0.13382753 0.27693186
0.59644095 0.71500764 0.04110751 0.95730081 0.91600724
0.47704678 0.26183479 0.34706971 0.07545431 0.29398385
0.93236070 0.60486023 0.48015011 0.08870451 0.45548581
0.91872718 0.38142712 0.10668643 0.01397541 0.04520355
0.93822273 0.18011940 0.57577277 0.91427606 0.30911399
0.95853475 0.23611214 0.69619891 0.69601980 0.76765372
0.58515930 0.49479057 0.11288752 0.97187699 0.32095365
0.57563608 0.40760618 0.78703383 0.43261152 0.90877651
0.84686346 0.10599030 0.72872803 0.19315490 0.66152912
0.10210518 0.06257876 0.47950688 0.47062066 0.72701157
0.48915116 0.66110261 0.60170685 0.24516994 0.12726050
0.03451185 0.90864994 0.83494878 0.94800035 0.91035206
0.14480751 0.88458997 0.53498312 0.15963215 0.55378627
0.35171349 0.28719791 0.09097957 0.00667896 0.32309622
0.87561479 0.42534520 0.91748977 0.73908457 0.41793223
0.99279792 0.87908370 0.28458072 0.59132853 0.98672190
0.28547393 0.09452165 0.89910674 0.53681109 0.37931425
0.62683489 0.56609740 0.24801549 0.52948179 0.98328855
0.66403523 0.55523786 0.75886666 0.84784685 0.86829981
0.71448906 0.84670080 0.43922919 0.20771016 0.64157936
0.25664246 0.73055695 0.86395782 0.65852932 0.99061803
0.40280575 0.39146298 0.07291005 0.97200603 0.20555729
0.59616495 0.08138254 0.45796388 0.33681125 0.33989127
0.18717090 0.53545811 0.60550838 0.86520709 0.34290701
0.72743276 0.73023855 0.34195926 0.65019733 0.02765254
0.72575740 0.32709576 0.03420866 0.26061893 0.56997511
0.28439072 0.84422744 0.77637570 0.55982168 0.06720327
0.58449067 0.71657369 0.15819609 0.58042821 0.07947911
0.40193792 0.11376012 0.88762938 0.67532159 0.71223735
0.27829114 0.04806073 0.21144026 0.58830274 0.04140071
0.43215628 0.12952729 0.94668759 0.87391019 0.98382450
0.27750768 0.90849647 0.90962737 0.59269720 0.96102026
0.49544979 0.32007095 0.62585546 0.03119821 0.85953001
0.22017528 0.05834068 0.80731217 0.53799961 0.74166948
0.77426600 0.43938444 0.54862081 0.58575513 0.15886492
0.73214332 0.11649057 0.77463977 0.85788827 0.17061997
0.66838056 0.96076133 0.07949296 0.68521946 0.89986254
0.05667410 0.12741385 0.83470977 0.63969104 0.46612929
0.10200126 0.01194925 0.10476340 0.90285217 0.31221221
0.32980614 0.46041971 0.52024973 0.05425470 0.28330912
0.60426543 0.00598243 0.97244013 0.21135841 0.78561597
0.78428734 0.63422849 0.32909934 0.44771136 0.27380750
0.14966697 0.18156268 0.65686758 0.28726350 0.97074787
0.63676171 0.96649494 0.24526295 0.08297372 0.54257548
0.03166785 0.33735355 0.15946671 0.02102971 0.46228045
0.11892296 0.33408336 0.29875681 0.29847692 0.73767569
0.02080745 0.62980060 0.08082293 0.22993106 0.25031439
0.87787525 0.45150053 0.13673441 0.63407612 0.97907688
0.52241942 0.50580158 0.06273902 0.05270283 0.77031811
0.05113352 0.24393329 0.75036441 0.37436336 0.22877652
0.59975358 0.85707591 0.88691457 0.85547165 0.36641027
0.58720133 0.45462835 0.09243817 0.32981586 0.07820411
0.25421519 0.36004706 0.60092307 0.46192412 0.36758683
0.98424170 0.08019934 0.68594024 0.45826386 0.29962317
0.79365413 0.89231296 0.49478547 0.87645944 0.23590734
0.28106737 0.75026285 0.08136314 0.79582424 0.76010628
0.82792971 0.27947652 0.72482861 0.82191216 0.46171689
0.79189752 0.96043686 0.51609668 0.88995725 0.28998963
0.55191845 0.03934737 0.83033700 0.49553013 0.98009549
0.19017594 0.98347750 0.33452066 0.87144372 0.72106301
0.71272114 0.71465963 0.88361677 0.85571283 0.73782329
0.20920458 0.34855153 0.46766817 0.02780062 0.74898344
0.03680650 0.44866557 0.77426312 0.91025891 0.25195236
0.87319953 0.63265037 0.25552148 0.27422476 0.95217406
0.39281839 0.66441573 0.09158900 0.94515992 0.07800798
0.02507888 0.39901462 0.17382573 0.12141278 0.85502334
0.19902911 0.02160210 0.44460522 0.14688742 0.68020336
0.71323733 0.60922473 0.95400380 0.99611159 0.90897777
0.41073520 0.66206647 0.32064685 0.62805003 0.50677209
0.52690101 0.87473387 0.73918362 0.39826974 0.43683919
0.80459118 0.32422684 0.01958019 0.95319576 0.98326137
0.83931735 0.69060863 0.33671416 0.68062550 0.65152380
0.33392969 0.03451730 0.95227244 0.68200635 0.85074171
0.64721009 0.51234433 0.73402047 0.00969637 0.93835057
0.80803854 0.31485260 0.20089527 0.01323282 0.59933780
0.31584602 0.20209563 0.33754800 0.68604181 0.24443049
0.19952227 0.78162632 0.10336988 0.11360736 0.23536740
0.23262256 0.67803776 0.48749791 0.74658435 0.92156640
0.56706407 0.36683221 0.99157136 0.23421374 0.45183767
0.91609720 0.85573315 0.37706276 0.77042618 0.30891908
0.40709595 0.06944866 0.61342849 0.88817388 0.58734506
0.98711323 0.14744128 0.63242656 0.87704136 0.68347125
0.84446569 0.43265239 0.25146321 0.04130111 0.34259839
0.92697368 0.40878778 0.56990338 0.76204273 0.19820348
0.66314909 0.02482844 0.06669207 0.50205581 0.26084093
0.65139159 0.41650223 0.09733904 0.56344203 0.62651696
0.67332139 0.58037374 0.47258086 0.21010758 0.05713135
0.89390629 0.10781246 0.32037450 0.07628388 0.34227964
0.42190597 0.58201860 0.77363549 0.49595133 0.86031236
0.83906769 0.81098161 0.26694195 0.14215941 0.88210306
0.53634237 0.12090720 0.82480459 0.75930318 0.31847147
0.92768077 0.01037616 0.56201727 0.88107122 0.35925856
0.85860762 0.61109408 0.70408301 0.58434977 0.92192494
0.62667915 0.75988365 0.06858761 0.36156496 0.58057195
0.13636150 0.57719713 0.59340255 0.63530602 0.22976282
0.71915530 0.41162531 0.63979565 0.09931342 0.79344045
0.10893790 0.84450224 0.23122236 0.99485593 0.73637397
0.17276368 0.13357764 0.74965804 0.64991737 0.61990341
0.41523170 0.05878239 0.05687301 0.05497131 0.42868366
0.42571090 0.25810502 0.89642955 0.30439758 0.39310223
0.11357431 0.04288255 0.23397550 0.11200634 0.85621396
0.89733974 0.37508865 0.42077265 0.68597384 0.72781399
0.19296476 0.61699087 0.31667128 0.67756410 0.00177323
0.05725176 0.79474693 0.18885238 0.06724856 0.68193156
0.42202167 0.22082041 0.28554673 0.64995708 0.87851940
0.29124547 0.61009521 0.87374537 0.05743712 0.69902994
0.81925115 0.45653873 0.37236821 0.31118709 0.52734307
0.39672836 0.38185294 0.30163915 0.17374510 0.04913278
0.90404879 0.25742801 0.58266467 0.97663209 0.79823377
0.36437958 0.15206043 0.26529938 0.22690047 0.05839021
0.84721160 0.18622435 0.37809403 0.55706977 0.49828704
0.47659049 0.24289680 0.88477595 0.07807463 0.56245739
0.73490635 0.21099431 0.13164942 0.75840044 0.66877037
0.28988183 0.44046090 0.24967434 0.80048356 0.26029740
0.30416821 0.64151867 0.52067892 0.12880774 0.85465381
0.02690525 0.19149288 0.49630295 0.79682619 0.43566145
0.00288078 0.81484193 0.03763639 0.68529083 0.01339574
0.38405386 0.30537067 0.22994703 0.44000045 0.27217985
0.53831243 0.02870435 0.86282045 0.61831306 0.09164956
0.25609707 0.07445781 0.72185784 0.90058883 0.30070608
0.94476583 0.56822213 0.21933909 0.96772793 0.80063440
0.26307906 0.31183306 0.16501252 0.55436179 0.68562285
0.23829083 0.86511559 0.57868991 0.81888344 0.20126869
0.93172350 0.66028129 0.21786948 0.78515828 0.10262106
0.35390326 0.79303876 0.63427924 0.90479631 0.31024934
0.60635447 0.56198079 0.63573813 0.91854197 0.99701497
0.83085849 0.31692291 0.01925964 0.97446405 0.98751283
0.60944293 0.13751018 0.69519957 0.68956636 0.56969015
0.46440193 0.88341765 0.36754434 0.89223647 0.39786427
0.85055280 0.12749961 0.79452122 0.89449784 0.14567830
0.45716830 0.74822309 0.28200437 0.42546044 0.17464886
0.68308746 0.65496587 0.52935411 0.12736159 0.61523955
0.81590528 0.63107864 0.39786553 0.20102294 0.53292914
0.75485590 0.59847044 0.32861691 0.12125866 0.58917183
0.07638293 0.86845380 0.29192617 0.03989733 0.52180460
0.32503407 0.64071852 0.69516575 0.74254998 0.54587026
0.48713246 0.32920155 0.08719954 0.63497059 0.54328459
0.64178757 0.45583809 0.70694291 0.85212760 0.86074305
0.33163422 0.85739792 0.59908488 0.74566046 0.72157152

65
3rdparty/mt19937ar/mtTest.c vendored Normal file
View File

@ -0,0 +1,65 @@
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Copyright (C) 2005, Mutsuo Saito,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
#include <stdio.h>
#include "mt19937ar.h"
int main(void)
{
int i;
unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
init_by_array(init, length);
printf("1000 outputs of genrand_int32()\n");
for (i=0; i<1000; i++) {
printf("%10lu ", genrand_int32());
if (i%5==4) printf("\n");
}
printf("\n1000 outputs of genrand_real2()\n");
for (i=0; i<1000; i++) {
printf("%10.8f ", genrand_real2());
if (i%5==4) printf("\n");
}
return 0;
}

79
3rdparty/mt19937ar/readme-mt.txt vendored Normal file
View File

@ -0,0 +1,79 @@
This is a Mersenne Twister pseudorandom number generator
with period 2^19937-1 with improved initialization scheme,
modified on 2002/1/26 by Takuji Nishimura and Makoto Matsumoto.
modified on 2005/4/26 by Mutsuo Saito
Contents of this tar ball:
readme-mt.txt this file
mt19937ar.c the C source (ar: initialize by ARray)
mt19937ar.h the C header file for mt19937ar
mtTest.c the C test main program of mt19937ar.c
mt19937ar.out Test outputs of six types generators. 1000 for each
1. Initialization
The initialization scheme for the previous versions of MT
(e.g. 1999/10/28 version or earlier) has a tiny problem, that
the most significant bits of the seed is not well reflected
to the state vector of MT.
This version (2002/1/26) has two initialization schemes:
init_genrand(seed) and init_by_array(init_key, key_length).
init_genrand(seed) initializes the state vector by using
one unsigned 32-bit integer "seed", which may be zero.
init_by_array(init_key, key_length) initializes the state vector
by using an array init_key[] of unsigned 32-bit integers
of length key_kength. If key_length is smaller than 624,
then each array of 32-bit integers gives distinct initial
state vector. This is useful if you want a larger seed space
than 32-bit word.
2. Generation
After initialization, the following type of pseudorandom numbers
are available.
genrand_int32() generates unsigned 32-bit integers.
genrand_int31() generates unsigned 31-bit integers.
genrand_real1() generates uniform real in [0,1] (32-bit resolution).
genrand_real2() generates uniform real in [0,1) (32-bit resolution).
genrand_real3() generates uniform real in (0,1) (32-bit resolution).
genrand_res53() generates uniform real in [0,1) with 53-bit resolution.
Note: the last five functions call the first one.
if you need more speed for these five functions, you may
suppress the function call by copying genrand_int32() and
replacing the last return(), following to these five functions.
3. main()
main() is an example to initialize with an array of length 4,
then 1000 outputs of unsigned 32-bit integers,
then 1000 outputs of real [0,1) numbers.
4. The outputs
The output of the mt19937ar.c is in the file mt19937ar.out.
If you revise or translate the code, check the output
by using this file.
5. Cryptography
This generator is not cryptoraphically secure.
You need to use a one-way (or hash) function to obtain
a secure random sequence.
6. Correspondence
See:
URL http://www.math.keio.ac.jp/matumoto/emt.html
email matumoto@math.keio.ac.jp, nisimura@sci.kj.yamagata-u.ac.jp
7. Reference
M. Matsumoto and T. Nishimura,
"Mersenne Twister: A 623-Dimensionally Equidistributed Uniform
Pseudo-Random Number Generator",
ACM Transactions on Modeling and Computer Simulation,
Vol. 8, No. 1, January 1998, pp 3--30.
-------
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Copyright (C) 2005, Mutsuo Saito
All rights reserved.

69
3rdparty/mysql/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,69 @@
#
# local copy
#
if( WIN32 )
message( STATUS "Detecting local MYSQL" )
find_path( MYSQL_LOCAL_INCLUDE_DIRS "mysql.h"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/include"
NO_DEFAULT_PATH )
find_library( MYSQL_LOCAL_LIBRARIES
NAMES libmysql
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/lib"
NO_DEFAULT_PATH )
mark_as_advanced( MYSQL_LOCAL_LIBRARIES )
mark_as_advanced( MYSQL_LOCAL_INCLUDE_DIRS )
if( MYSQL_LOCAL_LIBRARIES AND MYSQL_LOCAL_INCLUDE_DIRS )
if( EXISTS "${MYSQL_LOCAL_INCLUDE_DIRS}/mysql_version.h" )
file( STRINGS "${MYSQL_LOCAL_INCLUDE_DIRS}/mysql_version.h" MYSQL_VERSION_H REGEX "^#define MYSQL_SERVER_VERSION[ \t]+\"[^\"]+\".*$" )
string( REGEX REPLACE "^.*MYSQL_SERVER_VERSION[ \t]+\"([^\"]+)\".*$" "\\1" MYSQL_SERVER_VERSION "${MYSQL_VERSION_H}" )
message( STATUS "Found MYSQL: ${MYSQL_LOCAL_LIBRARIES} (found version ${MYSQL_SERVER_VERSION})" )
else()
message( STATUS "Found MYSQL: ${MYSQL_LOCAL_LIBRARIES}" )
endif()
set( HAVE_LOCAL_MYSQL ON
CACHE BOOL "mysql client is available as a local copy")
mark_as_advanced( HAVE_LOCAL_MYSQL )
else()
foreach( _VAR MYSQL_LOCAL_LIBRARIES MYSQL_LOCAL_INCLUDE_DIRS )
if( NOT "${_VAR}" )
set( MISSING_VARS ${MISSING_VARS} ${_VAR} )
endif()
endforeach()
message( STATUS "Could NOT find MYSQL (missing: ${MISSING_VARS})" )
unset( HAVE_LOCAL_MYSQL CACHE )
endif()
message( STATUS "Detecting local MYSQL - done" )
endif( WIN32 )
#
# system
#
message( STATUS "Detecting system MYSQL" )
unset( MYSQL_LIBRARIES CACHE )
unset( MYSQL_INCLUDE_DIRS CACHE )
set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH} )
find_package( MYSQL )
set( MYSQL_SYSTEM_LIBRARIES "${MYSQL_LIBRARIES}"
CACHE PATH "system mysql libraries" )
set( MYSQL_SYSTEM_INCLUDE_DIRS "${MYSQL_INCLUDE_DIRS}"
CACHE PATH "system mysql include directories" )
mark_as_advanced( MYSQL_SYSTEM_LIBRARIES )
mark_as_advanced( MYSQL_SYSTEM_INCLUDE_DIRS )
if( MYSQL_SYSTEM_LIBRARIES AND MYSQL_SYSTEM_INCLUDE_DIRS )
set( HAVE_SYSTEM_MYSQL ON
CACHE BOOL "mysql client is available on the system" )
mark_as_advanced( HAVE_SYSTEM_MYSQL )
else()
unset( HAVE_SYSTEM_MYSQL CACHE )
endif()
message( STATUS "Detecting system MYSQL - done" )
#
# configure
#
CONFIGURE_WITH_LOCAL_OR_SYSTEM( MYSQL )

35
3rdparty/mysql/FindMYSQL.cmake vendored Normal file
View File

@ -0,0 +1,35 @@
# - Find mysqlclient
# Find the native MySQL includes and library
#
# MYSQL_INCLUDE_DIRS - where to find mysql.h, etc.
# MYSQL_LIBRARIES - mysqlclient library.
# MYSQL_FOUND - True if mysqlclient is found.
#
find_path( MYSQL_INCLUDE_DIRS "mysql.h"
PATHS
"/usr/include/mysql"
"/usr/local/include/mysql"
"$ENV{PROGRAMFILES}/MySQL/*/include"
"$ENV{SYSTEMDRIVE}/MySQL/*/include" )
find_library( MYSQL_LIBRARIES
NAMES "mysqlclient" "mysqlclient_r"
PATHS
"/usr/lib/mysql"
"/usr/local/lib/mysql"
"$ENV{PROGRAMFILES}/MySQL/*/lib"
"$ENV{SYSTEMDRIVE}/MySQL/*/lib" )
mark_as_advanced( MYSQL_LIBRARIES MYSQL_INCLUDE_DIRS )
if( MYSQL_INCLUDE_DIRS AND EXISTS "${MYSQL_INCLUDE_DIRS}/mysql_version.h" )
file( STRINGS "${MYSQL_INCLUDE_DIRS}/mysql_version.h" MYSQL_VERSION_H REGEX "^#define[ \t]+MYSQL_SERVER_VERSION[ \t]+\"[^\"]+\".*$" )
string( REGEX REPLACE "^.*MYSQL_SERVER_VERSION[ \t]+\"([^\"]+)\".*$" "\\1" MYSQL_VERSION_STRING "${MYSQL_VERSION_H}" )
endif()
# handle the QUIETLY and REQUIRED arguments and set MYSQL_FOUND to TRUE if
# all listed variables are TRUE
include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( MYSQL
REQUIRED_VARS MYSQL_LIBRARIES MYSQL_INCLUDE_DIRS
VERSION_VAR MYSQL_VERSION_STRING )

66
3rdparty/pcre/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,66 @@
#
# local copy
#
if( WIN32 )
message( STATUS "Detecting local PCRE" )
find_path( PCRE_LOCAL_INCLUDE_DIRS "pcre.h"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/include"
NO_DEFAULT_PATH )
find_library( PCRE_LOCAL_LIBRARIES
NAMES pcre
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/lib"
NO_DEFAULT_PATH )
mark_as_advanced( PCRE_LOCAL_LIBRARIES )
mark_as_advanced( PCRE_LOCAL_INCLUDE_DIRS )
if( PCRE_LOCAL_LIBRARIES AND PCRE_LOCAL_INCLUDE_DIRS )
file( STRINGS "${PCRE_LOCAL_INCLUDE_DIRS}/pcre.h" PCRE_H REGEX "^#define[ \t]+PCRE_M[A-Z]+[ \t]+[0-9]+.*$" )
string( REGEX REPLACE "^.*PCRE_MAJOR[ \t]+([0-9]+).*$" "\\1" PCRE_MAJOR "${PCRE_H}" )
string( REGEX REPLACE "^.*PCRE_MINOR[ \t]+([0-9]+).*$" "\\1" PCRE_MINOR "${PCRE_H}" )
message( STATUS "Found PCRE: ${PCRE_LOCAL_LIBRARIES} (found version ${PCRE_MAJOR}.${PCRE_MINOR})" )
set( HAVE_LOCAL_PCRE ON
CACHE BOOL "pcre is available as a local copy" )
mark_as_advanced( HAVE_LOCAL_PCRE )
else()
foreach( _VAR PCRE_LOCAL_LIBRARIES PCRE_LOCAL_INCLUDE_DIRS )
if( NOT "${_VAR}" )
set( MISSING_VARS ${MISSING_VARS} ${_VAR} )
endif()
endforeach()
message( STATUS "Could NOT find PCRE (missing: ${MISSING_VARS})" )
unset( HAVE_LOCAL_PCRE CACHE )
endif()
message( STATUS "Detecting local PCRE - done" )
endif( WIN32 )
#
# system
#
message( STATUS "Detecting system PCRE" )
set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH} )
unset( PCRE_LIBRARIES CACHE )
unset( PCRE_INCLUDE_DIRS CACHE )
find_package( PCRE )
set( PCRE_SYSTEM_LIBRARIES ${PCRE_LIBRARIES}
CACHE PATH "system pcre libraries" )
set( PCRE_SYSTEM_INCLUDE_DIRS ${PCRE_INCLUDE_DIRS}
CACHE PATH "system pcre include directories" )
mark_as_advanced( PCRE_SYSTEM_LIBRARIES )
mark_as_advanced( PCRE_SYSTEM_INCLUDE_DIRS )
if( PCRE_SYSTEM_LIBRARIES AND PCRE_SYSTEM_INCLUDE_DIRS )
set( HAVE_SYSTEM_PCRE ON
CACHE BOOL "pcre is available on the system" )
mark_as_advanced( HAVE_SYSTEM_PCRE )
else()
unset( HAVE_SYSTEM_PCRE CACHE )
endif()
message( STATUS "Detecting system PCRE - done" )
#
# configure
#
CONFIGURE_WITH_LOCAL_OR_SYSTEM( PCRE )

35
3rdparty/pcre/FindPCRE.cmake vendored Normal file
View File

@ -0,0 +1,35 @@
# - Find pcre
# Find the native PCRE includes and library
#
# PCRE_INCLUDE_DIRS - where to find pcre.h
# PCRE_LIBRARIES - List of libraries when using pcre.
# PCRE_FOUND - True if pcre found.
find_path( PCRE_INCLUDE_DIR pcre.h )
set( PCRE_NAMES pcre )
find_library( PCRE_LIBRARY NAMES ${PCRE_NAMES} )
mark_as_advanced( PCRE_LIBRARY PCRE_INCLUDE_DIR )
if( PCRE_INCLUDE_DIR AND EXISTS "${PCRE_INCLUDE_DIR}/pcre.h" )
file( STRINGS "${PCRE_INCLUDE_DIR}/pcre.h" PCRE_H REGEX "^#define[ \t]+PCRE_M[A-Z]+[ \t]+[0-9]+.*$" )
string( REGEX REPLACE "^.*PCRE_MAJOR[ \t]+([0-9]+).*$" "\\1" PCRE_MAJOR "${PCRE_H}" )
string( REGEX REPLACE "^.*PCRE_MINOR[ \t]+([0-9]+).*$" "\\1" PCRE_MINOR "${PCRE_H}" )
set( PCRE_VERSION_STRING "${PCRE_MAJOR}.${PCRE_MINOR}" )
set( PCRE_VERSION_MAJOR "${PCRE_MAJOR}" )
set( PCRE_VERSION_MINOR "${PCRE_MINOR}" )
endif()
# handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if
# all listed variables are TRUE
include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( PCRE
REQUIRED_VARS PCRE_LIBRARY PCRE_INCLUDE_DIR
VERSION_VAR PCRE_VERSION_STRING )
if( PCRE_FOUND )
set( PCRE_LIBRARIES ${PCRE_LIBRARY} )
set( PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR} )
endif()

64
3rdparty/zlib/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,64 @@
#
# local copy
#
if( WIN32 )
message( STATUS "Detecting local ZLIB" )
find_path( ZLIB_LOCAL_INCLUDE_DIRS "zlib.h"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/include"
NO_DEFAULT_PATH )
find_library( ZLIB_LOCAL_LIBRARIES
NAMES zdll
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/lib"
NO_DEFAULT_PATH )
mark_as_advanced( ZLIB_LOCAL_LIBRARIES )
mark_as_advanced( ZLIB_LOCAL_INCLUDE_DIRS )
if( ZLIB_LOCAL_LIBRARIES AND ZLIB_LOCAL_INCLUDE_DIRS )
file( STRINGS "${ZLIB_LOCAL_INCLUDE_DIRS}/zlib.h" ZLIB_H REGEX "^#define[ \t]+ZLIB_VERSION[ \t]+\"[^\"]+\".*$" )
string( REGEX REPLACE "^.*ZLIB_VERSION[ \t]+\"([^\"]+)\".*$" "\\1" ZLIB_VERSION "${ZLIB_H}" )
message( STATUS "Found local ZLIB: ${ZLIB_LOCAL_LIBRARIES} (found version ${ZLIB_VERSION})" )
set( HAVE_LOCAL_ZLIB ON
CACHE BOOL "zlib is available as a local copy" )
mark_as_advanced( HAVE_LOCAL_ZLIB )
else()
foreach( _VAR ZLIB_LOCAL_LIBRARIES ZLIB_LOCAL_INCLUDE_DIRS )
if( NOT "${_VAR}" )
set( MISSING_VARS ${MISSING_VARS} ${_VAR} )
endif()
endforeach()
message( STATUS "Could NOT find local ZLIB (missing: ${MISSING_VARS})" )
unset( HAVE_LOCAL_ZLIB CACHE )
endif()
message( STATUS "Detecting local ZLIB - done" )
endif( WIN32 )
#
# system
#
message( STATUS "Detecting system ZLIB" )
unset( ZLIB_LIBRARIES CACHE )
unset( ZLIB_INCLUDE_DIRS CACHE )
find_package( ZLIB )
set( ZLIB_SYSTEM_LIBRARIES ${ZLIB_LIBRARIES}
CACHE PATH "system zlib libraries" )
set( ZLIB_SYSTEM_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS}
CACHE PATH "system zlib include directories" )
mark_as_advanced( ZLIB_SYSTEM_LIBRARIES )
mark_as_advanced( ZLIB_SYSTEM_INCLUDE_DIRS )
if( ZLIB_SYSTEM_LIBRARIES AND ZLIB_SYSTEM_INCLUDE_DIRS )
set( HAVE_SYSTEM_ZLIB ON
CACHE BOOL "zlib is available on the system" )
mark_as_advanced( HAVE_SYSTEM_ZLIB )
else()
unset( HAVE_SYSTEM_ZLIB CACHE )
endif()
message( STATUS "Detecting system ZLIB - done" )
#
# configure
#
CONFIGURE_WITH_LOCAL_OR_SYSTEM( ZLIB )

265
CMakeLists.txt Normal file
View File

@ -0,0 +1,265 @@
# "Getting Started with CMake", a tutorial video by Eric Wing.
# Part 1 of 6: http://www.youtube.com/watch?v=CLvZTyji_Uw
# Part 2 of 6: http://www.youtube.com/watch?v=gUW-RrRQjEg
# Part 3 of 6: http://www.youtube.com/watch?v=sz6cPhbuTk4
# Part 4 of 6: http://www.youtube.com/watch?v=JICZOkyNXbg
# Part 5 of 6: http://www.youtube.com/watch?v=lAiuLHy4dCk
# Part 6 of 6: http://www.youtube.com/watch?v=fAtJNzDZdH8
#
# You can use notepad++ for syntax highlighting.
# Naming conventions:
# WITH_* : option to use an external package or not
# ENABLE_* : option to use an internal feature/code or not
# HAVE_* : internal variable indicating if we have and are using something
cmake_minimum_required( VERSION 2.8.4 )
project( eAthena )
#
# Prevent building in the source directory by default
#
if( ALLOW_SAME_DIRECTORY )
elseif( "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" )
option( ALLOW_SAME_DIRECTORY "Allow CMake to build in the source directory." OFF )
message( FATAL_ERROR "Do not use the source directory to build your files, instead create a separate folder and build there.\nExample:\n mkdir build\n cd build\n cmake -G\"Unix Makefiles\" ..\n make install\nTo skip this check, set ALLOW_SAME_DIRECTORY to 1 or ON" )
endif()
#
# Global stuff
#
set( GLOBAL_LIBRARIES CACHE INTERNAL "" )
set( GLOBAL_INCLUDE_DIRS CACHE INTERNAL "" )
set( GLOBAL_DEFINITIONS CACHE INTERNAL "" )
mark_as_advanced( GLOBAL_LIBRARIES GLOBAL_INCLUDE_DIRS GLOBAL_DEFINITIONS )
if( WIN32 )
list( APPEND GLOBAL_DEFINITIONS FD_SETSIZE=4096 )
list( APPEND GLOBAL_LIBRARIES "oldnames.lib" "ws2_32.lib" )
endif()
if( MSVC )
list( APPEND GLOBAL_DEFINITIONS _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE DB_MANUAL_CAST_TO_UNION )
endif()
#
# Find svnversion
#
message( STATUS "Detecting svnversion" )
find_program( SVNVERSION_EXECUTABLE svnversion )
mark_as_advanced( SVNVERSION_EXECUTABLE )
if( SVNVERSION_EXECUTABLE )
message( STATUS "Found svnversion: ${SVNVERSION_EXECUTABLE}" )
endif()
message( STATUS "Detecting svnversion - done" )
#
# Find Subversion
#
message( STATUS "Detecting Subversion" )
find_package( Subversion )
message( STATUS "Detecting Subversion - done" )
#
# Find math library (FreeBSD)
#
message( STATUS "Detecting math library" )
find_library( M_LIBRARIES m )
mark_as_advanced( M_LIBRARIES )
if( M_LIBRARIES )
message( STATUS "Found m: ${M_LIBRARIES}" )
list( APPEND GLOBAL_LIBRARIES ${M_LIBRARIES} )
endif()
message( STATUS "Detecting math library - done" )
#
# PACKETVER
#
set( PACKETVER CACHE STRING "Sets the PACKETVER define of the servers. (see src/common/mmo.h)" )
if( PACKETVER )
list( APPEND GLOBAL_DEFINITIONS PACKETVER=${PACKETVER} )
endif()
#
# SVNVERSION
#
if( SVNVERSION_EXECUTABLE )
execute_process( COMMAND ${SVNVERSION_EXECUTABLE} ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE SVNVERSION
OUTPUT_STRIP_TRAILING_WHITESPACE )
string( REGEX REPLACE "[^1234567890MSexported]" "_" SVNVERSION ${SVNVERSION} )
endif()
if( Subversion_FOUND AND SVNVERSION )
Subversion_WC_INFO( ${PROJECT_SOURCE_DIR} eAthena )
if( eAthena_WC_URL )
string( REGEX MATCH "[^/]+$" BRANCH ${eAthena_WC_URL} )
set( SVNVERSION "${BRANCH}-${SVNVERSION}" )
endif()
endif()
#####################################################################
# package stuff
#
set( CPACK_PACKAGE_NAME "eAthena" )
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "MMORPG server package" )
set( CPACK_PACKAGE_VERSION ${SVNVERSION} )
set( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE )
#set( CPACK_MONOLITHIC_INSTALL ON )
include( CPACK OPTIONAL RESULT_VARIABLE HAVE_CPACK )
if( NOT HAVE_CPACK )
# empty replacements
macro( cpack_add_component_group )
endmacro()
macro( cpack_add_component )
endmacro()
message( STATUS "CPACK not found, package creation disabled" )
endif()
set( Runtime "Runtime files" CACHE INTERNAL "" )
set( Runtime_base "configurations, dbs, npcs, docs, ..." CACHE INTERNAL "" )
set( Runtime_templates "conf/import and save (generated from conf/import-tmpl and save-tmpl)" CACHE INTERNAL "" )
cpack_add_component_group( Runtime DESCRIPTION ${Runtime} DISPLAY_NAME "Runtime" )
cpack_add_component( Runtime_base DESCRIPTION ${Runtime_base} DISPLAY_NAME "Base files" GROUP Runtime )
cpack_add_component( Runtime_templates DESCRIPTION ${Runtime_templates} DISPLAY_NAME "Base templates" GROUP Runtime )
set( Development "Development files" CACHE INTERNAL "" )
set( Development_base "projects, 3rdparty, sources, templates" CACHE INTERNAL "" )
cpack_add_component_group( Development DESCRIPTION ${Development} DISPLAY_NAME "Development" )
cpack_add_component( Development_base DESCRIPTION ${Development_base} DISPLAY_NAME "Base files" GROUP Development )
#
# install stuff
#
option( WITH_COMPONENT_RUNTIME "install/package files needed to run the project" ON )
option( WITH_COMPONENT_DEVELOPMENT "install/package files needed to build the project" OFF )
option( INSTALL_TO_PATH "copy files to INSTALL_PATH" OFF )
option( INSTALL_TO_SOURCE "copy files to source directory, skips what is already there (${CMAKE_CURRENT_SOURCE_DIR})" OFF )
option( INSTALL_TO_SUBDIR "copy files to subdirectory (${CMAKE_CURRENT_BINARY_DIR}/install)" OFF )
set( INSTALL_PATH "${CMAKE_INSTALL_PREFIX}" CACHE STRING "install path (only used when INSTALL_TO_PATH is set)" )
mark_as_advanced( CMAKE_INSTALL_PREFIX )
if( INSTALL_TO_PATH AND NOT ("${INSTALL_TO}" STREQUAL "path") )# changed to path
set_property( CACHE INSTALL_TO_SOURCE INSTALL_TO_SUBDIR PROPERTY VALUE OFF )
elseif( INSTALL_TO_SOURCE AND NOT ("${INSTALL_TO}" STREQUAL "source") )# changed to source
set_property( CACHE INSTALL_TO_PATH INSTALL_TO_SUBDIR PROPERTY VALUE OFF )
elseif( INSTALL_TO_SUBDIR AND NOT ("${INSTALL_TO}" STREQUAL "subdir") )# changed to subdir
set_property( CACHE INSTALL_TO_PATH INSTALL_TO_SOURCE PROPERTY VALUE OFF )
elseif( NOT INSTALL_TO_PATH AND NOT INSTALL_TO_SOURCE AND NOT INSTALL_TO_SUBDIR )# default
set_property( CACHE INSTALL_TO_SUBDIR PROPERTY VALUE ON )
endif()
if( INSTALL_TO_PATH )
set( INSTALL_TO "path" CACHE INTERNAL "" )
set_property( CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${INSTALL_PATH}" )
elseif( INSTALL_TO_SOURCE )
set( INSTALL_TO "source" CACHE INTERNAL "" )
set_property( CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${CMAKE_CURRENT_SOURCE_DIR}" )
elseif( INSTALL_TO_SUBDIR )
set( INSTALL_TO "subdir" CACHE INTERNAL "" )
set_property( CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${CMAKE_CURRENT_BINARY_DIR}/install" )
endif()
set( SVN_FOLDER_PATTERN "[\\.]svn" CACHE STRING "pattern of svn folder that we exclude from instalations" )
mark_as_advanced( SVN_FOLDER_PATTERN )
set( DEVELOPMENT_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/configure"
"${CMAKE_CURRENT_SOURCE_DIR}/configure.in"
"${CMAKE_CURRENT_SOURCE_DIR}/eAthena-6.dsw"
"${CMAKE_CURRENT_SOURCE_DIR}/eAthena-7.1.sln"
"${CMAKE_CURRENT_SOURCE_DIR}/eAthena-8.sln"
"${CMAKE_CURRENT_SOURCE_DIR}/eAthena-9.sln"
"${CMAKE_CURRENT_SOURCE_DIR}/eAthena-10.sln"
)
set( DEVELOPMENT_DIRECTORIES
"3rdparty"
"conf/import-tmpl"
"save-tmpl"
"src"
"vcproj-6"
"vcproj-7.1"
"vcproj-8"
"vcproj-9"
"vcproj-10"
)
set( RUNTIME_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/athena-start"
"${CMAKE_CURRENT_SOURCE_DIR}/Changelog-Trunk.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/char-server.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/charserv-sql.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/charserv.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/dbghelp.dll"
"${CMAKE_CURRENT_SOURCE_DIR}/libmysql.dll"
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
"${CMAKE_CURRENT_SOURCE_DIR}/login-server.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/logserv-sql.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/logserv.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/map-server.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/mapserv-sql.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/mapserv.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/notice.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/pcre3.dll"
"${CMAKE_CURRENT_SOURCE_DIR}/readme.html"
"${CMAKE_CURRENT_SOURCE_DIR}/runserver-sql.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/runserver.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/serv.bat"
"${CMAKE_CURRENT_SOURCE_DIR}/start"
"${CMAKE_CURRENT_SOURCE_DIR}/zlib1.dll"
)
set( RUNTIME_DIRECTORIES
"conf"
"db"
"doc"
"log"
"npc"
"plugins"
"readme"
"sql-files"
"tools"
)
if( INSTALL_TO_SOURCE )# skip, already in the source dir
else()
if( WITH_COMPONENT_RUNTIME )
install( FILES ${RUNTIME_FILES}
DESTINATION "."
COMPONENT Runtime_base )
foreach( DIR IN ITEMS ${RUNTIME_DIRECTORIES} )
install( DIRECTORY "${DIR}/"
DESTINATION "${DIR}"
COMPONENT Runtime_base
PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE
PATTERN "conf/import-tmpl" EXCLUDE )
endforeach()
endif()
if( WITH_COMPONENT_DEVELOPMENT )
install( FILES ${DEVELOPMENT_FILES}
DESTINATION "."
COMPONENT Development_base )
foreach( DIR IN ITEMS ${DEVELOPMENT_DIRECTORIES} )
install( DIRECTORY "${DIR}/"
DESTINATION "${DIR}"
COMPONENT Development_base
PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
endforeach()
endif()
endif()
if( WITH_COMPONENT_RUNTIME )
# templates
install( DIRECTORY "save-tmpl/"
DESTINATION "save"
COMPONENT Runtime_templates
PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
install( DIRECTORY "conf/import-tmpl/"
DESTINATION "conf/import"
COMPONENT Runtime_templates
PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
endif()
#
# subdirectories
#
add_subdirectory( 3rdparty )
add_subdirectory( src )

View File

@ -1,5 +1,7 @@
Date Added
2011/07/10
* Merged changes from trunk [14827:14894/trunk]. [Ai4rei]
2011/06/13
* Fixed 3rd classes not being able to level up after Base Level reset. [Gepard]
2011/05/15

View File

@ -2,15 +2,15 @@
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
ALL_DEPENDS=common common_sql login login_sql char char_sql map map_sql tools converters import save
SQL_DEPENDS=common_sql login_sql char_sql map_sql import save
COMMON_SQL_DEPENDS=
LOGIN_SQL_DEPENDS=common_sql
CHAR_SQL_DEPENDS=common_sql
MAP_SQL_DEPENDS=common_sql
ALL_DEPENDS=mt19937ar common common_sql login login_sql char char_sql map map_sql tools converters import save
SQL_DEPENDS=mt19937ar common_sql login_sql char_sql map_sql import save
COMMON_SQL_DEPENDS=mt19937ar
LOGIN_SQL_DEPENDS=mt19937ar common_sql
CHAR_SQL_DEPENDS=mt19937ar common_sql
MAP_SQL_DEPENDS=mt19937ar common_sql
CONVERTERS_DEPENDS=common_sql
else
ALL_DEPENDS=common login char map tools import save
ALL_DEPENDS=mt19937ar common login char map tools import save
SQL_DEPENDS=needs_mysql
COMMON_SQL_DEPENDS=needs_mysql
LOGIN_SQL_DEPENDS=needs_mysql
@ -18,6 +18,10 @@ else
MAP_SQL_DEPENDS=needs_mysql
CONVERTERS_DEPENDS=needs_mysql
endif
COMMON_TXT_DEPENDS=mt19937ar
LOGIN_TXT_DEPENDS=mt19937ar common
CHAR_TXT_DEPENDS=mt19937ar common
MAP_TXT_DEPENDS=mt19937ar common
WITH_PLUGINS=@WITH_PLUGINS@
ifeq ($(WITH_PLUGINS),yes)
@ -30,6 +34,7 @@ endif
#####################################################################
.PHONY: txt sql conf \
common common_sql \
mt19937ar \
login login_sql \
char char_sql \
map map_sql \
@ -44,25 +49,28 @@ sql: $(SQL_DEPENDS)
conf: import save
common:
common: $(COMMON_TXT_DEPENDS)
@$(MAKE) -C src/common txt
common_sql: $(COMMON_SQL_DEPENDS)
@$(MAKE) -C src/common sql
login: common
mt19937ar:
@$(MAKE) -C 3rdparty/mt19937ar
login: $(LOGIN_TXT_DEPENDS)
@$(MAKE) -C src/login txt
login_sql: $(LOGIN_SQL_DEPENDS)
@$(MAKE) -C src/login sql
char: common
char: $(CHAR_TXT_DEPENDS)
@$(MAKE) -C src/char
char_sql: $(CHAR_SQL_DEPENDS)
@$(MAKE) -C src/char_sql
map: common
map: $(MAP_TXT_DEPENDS)
@$(MAKE) -C src/map txt
map_sql: $(MAP_SQL_DEPENDS)
@ -97,6 +105,7 @@ save:
clean:
@$(MAKE) -C src/common $@
@$(MAKE) -C 3rdparty/mt19937ar $@
@$(MAKE) -C src/login $@
@$(MAKE) -C src/char $@
@$(MAKE) -C src/char_sql $@
@ -110,6 +119,7 @@ help:
@echo "possible targets are:"
@echo "'common' - builds object files used in TXT servers"
@echo "'common_sql' - builds object files used in SQL servers"
@echo "'mt19937ar' - builds object file of Mersenne Twister MT19937"
@echo "'login' - builds login server (TXT version)"
@echo "'login_sql' - builds login server (SQL version)"
@echo "'char' - builds char server (TXT version)"

View File

@ -1,5 +1,7 @@
Date Added
2011/07/09
* Rev. 14892 Removed 'msg_athena.conf' messages 619 and 620 (duplicates to 572 and 573) (since r5506). [Ai4rei]
2011/05/13
* Rev. 14812 Added settings 'cashshop_show_points' and 'mail_show_status', both disabled by default, as the messages they control are custom (follow up to r11548 and r12264). [Ai4rei]
- Moved custom cash point update messages to 'msg_athena.conf' (IDs 504~506).

View File

@ -529,8 +529,8 @@
616: Taekwon
617: Star Gladiator
618: Soul Linker
619: Gunslinger
620: Ninja
//619: FREE
//620: FREE
621: Summer
//...
625: Rune Knight

4
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in Revision: 14767 .
# From configure.in Revision: 14870 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
@ -1333,6 +1333,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_files="$ac_config_files Makefile src/common/Makefile"
ac_config_files="$ac_config_files 3rdparty/mt19937ar/Makefile"
ac_config_files="$ac_config_files src/char/Makefile src/login/Makefile"
ac_config_files="$ac_config_files src/char_sql/Makefile src/txt-converter/Makefile"

View File

@ -6,6 +6,7 @@ AC_REVISION($Revision$)
AC_PREREQ([2.59])
AC_CONFIG_SRCDIR([src/common/cbasetypes.h])
AC_CONFIG_FILES([Makefile src/common/Makefile])
AC_CONFIG_FILES([3rdparty/mt19937ar/Makefile])
AC_CONFIG_FILES([src/char/Makefile src/login/Makefile])
AC_CONFIG_FILES([src/char_sql/Makefile src/txt-converter/Makefile])
AC_CONFIG_FILES([src/map/Makefile src/plugins/Makefile src/tool/Makefile])

View File

@ -1438,7 +1438,7 @@ packet_ver: 25
0x07fa,8
//2009-11-24aRagexeRE
//0x07fb,25
0x07fb,25
//2009-12-01aRagexeRE
//0x07fc,10

View File

@ -102,7 +102,7 @@ EAJL_UPPER:
EAJL_BABY:
Check if a class is an adopted class.
if (@job&EAJ_BABY)
if (@job&EAJL_BABY)
mes "Don't you hate being weak?";
EAJ_UPPERMASK:

View File

@ -4,7 +4,7 @@
//= A reference manual for the eAthena scripting language.
//= Commands are sorted depending on their functionality.
//===== Version ===========================================
//= 3.42.20110508
//= 3.45.20110709
//=========================================================
//= 1.0 - First release, filled will as much info as I could
//= remember or figure out, most likely there are errors,
@ -174,6 +174,13 @@
//= 3.42.20110508
//= Updated description of all instance commands to reflect actual behavior.
//= [Ai4rei]
//= 3.43.20110529
//= Updated 'npcshopitem', 'npcshopadditem' and 'npcshopdelitem' to support
//= cashshops as well. [Ai4rei]
//= 3.44.20110530
//= Documented special map names recognized by 'warpguild'. [Ai4rei]
//= 3.45.20110709
//= Added 'getmercinfo' command. [Ai4rei]
//=========================================================
This document is a reference manual for all the scripting commands and functions
@ -3689,6 +3696,13 @@ warpchar "prontera",150,100,20000001;
Warps a guild to specified map and coordinate given the guild id, which you can get with
getcharid(2). You can also request another guild id given the member's name with getcharid(2,<player_name>).
You can use the following "map names" for special warping behavior:
Random: All party members are randomly warped in their current map (as if they
all used a fly wing)
SavePointAll: All party members are warped to their respective save point.
SavePoint: All party members are warped to the save point of the currently
attached player (will fail if there's no player attached).
Example:
warpguild "prontera",x,y,Guild_ID;
@ -5660,7 +5674,7 @@ npcshopitem was used. After rechecking the source, I found what caused this.
*npcshopitem "<name>",<item id>,<price>{,<item id>,<price>{,<item id>,<price>{,...}}}
This command lets you override the contents of an existing NPC shop. The
This command lets you override the contents of an existing NPC shop or cashshop. The
current sell list will be wiped, and only the items specified with the price
specified will be for sale.
@ -5673,7 +5687,7 @@ Note that you cannot use -1 to specify default selling price!
*npcshopadditem "<name>",<item id>,<price>{,<item id>,<price>{,<item id>,<price>{,...}}}
This command will add more items at the end of the selling list for the
specified NPC shop. If you specify an item already for sell, that item will
specified NPC shop or cashshop. If you specify an item already for sell, that item will
appear twice on the sell list.
The function returns 1 if shop was updated successfully, or 0 if not found.
@ -5684,7 +5698,7 @@ Note that you cannot use -1 to specify default selling price!
*npcshopdelitem "<name>",<item id>{,<item id>{,<item id>{,...}}}
This command will remove items from the specified NPC shop.
This command will remove items from the specified NPC shop or cashshop.
If the item to remove exists more than once on the shop, all instances will be
removed.
@ -7160,5 +7174,26 @@ attached character. Guild can be one or the following constants:
---------------------------------------
*getmercinfo(<type>{,<char id>});
Retrieves information about mercenary of the currently attached
character. If char id is given, the information of that character is
retrieved instead. Type specifies what information to retrieve and
can be one of the following:
0 - Database ID
1 - Class
2 - Name
3 - Faith value for this mercenary's guild, if any
4 - Calls value for this mercenary's guild, if any
5 - Kill count
6 - Remaining life time in msec
7 - Level
If the character does not have a mercenary, the command returns ""
for name and 0 for all other types.
----------------------------------------
Whew.
That's about all of them.

View File

@ -3,19 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
###############################################################################
Project: "login_txt"=".\vcproj-6\login-server_txt.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "login_sql"=".\vcproj-6\login-server_sql.dsp" - Package Owner=<4>
Project: "char_sql"=".\vcproj-6\char-server_sql.dsp" - Package Owner=<4>
Package=<5>
{{{
@ -39,7 +27,7 @@ Package=<4>
###############################################################################
Project: "char_sql"=".\vcproj-6\char-server_sql.dsp" - Package Owner=<4>
Project: "login_sql"=".\vcproj-6\login-server_sql.dsp" - Package Owner=<4>
Package=<5>
{{{
@ -51,7 +39,7 @@ Package=<4>
###############################################################################
Project: "map_txt"=".\vcproj-6\map-server_txt.dsp" - Package Owner=<4>
Project: "login_txt"=".\vcproj-6\login-server_txt.dsp" - Package Owner=<4>
Package=<5>
{{{
@ -75,7 +63,7 @@ Package=<4>
###############################################################################
Project: "console"=".\vcproj-6\plugin-console.dsp" - Package Owner=<4>
Project: "map_txt"=".\vcproj-6\map-server_txt.dsp" - Package Owner=<4>
Package=<5>
{{{
@ -87,7 +75,55 @@ Package=<4>
###############################################################################
Project: "pid"=".\vcproj-6\plugin-pid.dsp" - Package Owner=<4>
Project: "mapcache"=".\vcproj-6\mapcache.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "plugin_console"=".\vcproj-6\plugin-console.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "plugin_pid"=".\vcproj-6\plugin-pid.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "txt_converter_char"=".\vcproj-6\txt-converter-char.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "txt_converter_login"=".\vcproj-6\txt-converter-login.dsp" - Package Owner=<4>
Package=<5>
{{{

View File

@ -3807,7 +3807,7 @@ OnTouch_:
soundeffect "tao_gunka_stand.wav",0;
sc_end SC_Blind;
sc_start SC_Curse,3000,0;
if (!lhz_curse == 6) set lhz_curse,7;
if (lhz_curse == 6) set lhz_curse,7;
}
}
end;
@ -3887,7 +3887,7 @@ OnTouch_:
mes "............";
next;
mes "............";
close;
close2;
soundeffect "tao_gunka_stand.wav",0;
sc_end SC_Blind;
sc_start SC_Curse,3000,0;
@ -4191,7 +4191,7 @@ lhz_in01,282,166,0 script #kiz10 -1,3,3,{
OnTouch_:
if (countitem(7345) > 0) {
if (lhz_curse == 16) {
if (checkweight(1201,1) == 1) {
if (checkweight(1201,1) == 0) {
mes "^3355FFThere's something on";
mes "the floor, but you can't";
mes "really take a good look at";
@ -5283,7 +5283,7 @@ OnTouch_:
else if ((BaseLevel > 89) && (BaseLevel < 151))
getexp 200000,100000;
}
end;
close;
}
lhz_in01,114,181,5 script Representative#li_01 71,{
@ -6220,7 +6220,7 @@ lhz_in01,286,226,3 script Secretary Slierre#li 831,{
else if (lhz_curse == 30) {
set .@li_keka,rand(1,10);
if (.@li_keka > 7) {
if (checkweight(1201,1) == 1) {
if (checkweight(1201,1) == 0) {
mes "[Sueii Slierre]";
mes "Oh, I'd like to have";
mes "a word with you. Would";

9
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
add_subdirectory( common )
add_subdirectory( login )
add_subdirectory( char )
add_subdirectory( char_sql )
add_subdirectory( map )
add_subdirectory( tool )
#add_subdirectory( txt-converter )
#add_subdirectory( plugins )

51
src/char/CMakeLists.txt Normal file
View File

@ -0,0 +1,51 @@
#
# char txt
#
if( HAVE_common_base )
message( STATUS "Creating target char-server" )
set( TXT_CHAR_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/char.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_party.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_status.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.h"
"${CMAKE_CURRENT_SOURCE_DIR}/inter.h"
)
set( TXT_CHAR_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/char.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_party.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_status.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.c"
"${CMAKE_CURRENT_SOURCE_DIR}/inter.c"
)
set( DEPENDENCIES common_base )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} TXT_ONLY )
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_CHAR_HEADERS} ${TXT_CHAR_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} )
source_group( char FILES ${TXT_CHAR_HEADERS} ${TXT_CHAR_SOURCES} )
include_directories( ${INCLUDE_DIRS} )
add_executable( char-server ${SOURCE_FILES} )
add_dependencies( char-server ${DEPENDENCIES} )
target_link_libraries( char-server ${LIBRARIES} ${DEPENDENCIES} )
set_target_properties( char-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
if( WITH_COMPONENT_RUNTIME )
cpack_add_component( Runtime_charserver_txt DESCRIPTION "char-server (txt version)" DISPLAY_NAME "char-server" GROUP Runtime )
install( TARGETS char-server
DESTINATION "."
COMPONENT Runtime_charserver_txt )
endif()
message( STATUS "Creating target char-server - done" )
set( HAVE_char-server ON CACHE BOOL "char-server target is available" )
mark_as_advanced( HAVE_char-server )
else()
message( STATUS "Skipping target char-server (requires common_base)" )
unset( HAVE_char-server CACHE )
endif()

View File

@ -3,12 +3,16 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/malloc.o ../common/obj_all/showmsg.o ../common/obj_all/utils.o \
../common/obj_all/strlib.o ../common/obj_all/grfio.o \
../common/obj_all/mapindex.o ../common/obj_all/ers.o
../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/random.o
COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
../common/malloc.h ../common/showmsg.h ../common/utils.h \
../common/strlib.h ../common/grfio.h \
../common/mapindex.h ../common/ers.h
../common/mapindex.h ../common/ers.h ../common/random.h
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
CHAR_OBJ = obj_txt/char.o obj_txt/inter.o obj_txt/int_party.o obj_txt/int_guild.o \
obj_txt/int_storage.o obj_txt/int_status.o obj_txt/int_pet.o obj_txt/int_homun.o
@ -21,8 +25,8 @@ CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_status.h int_p
all: char-server
char-server: obj_txt $(CHAR_OBJ) $(COMMON_OBJ)
@CC@ @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) @LIBS@
char-server: obj_txt $(CHAR_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ)
@CC@ @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@
clean:
rm -rf *.o obj_txt ../../char-server@EXEEXT@
@ -39,9 +43,12 @@ help:
obj_txt:
-mkdir obj_txt
obj_txt/%.o: %.c $(CHAR_H) $(COMMON_H)
@CC@ @CFLAGS@ -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_txt/%.o: %.c $(CHAR_H) $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing common object files
# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common txt
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar

View File

@ -176,7 +176,7 @@ struct online_char_data {
};
static DBMap* online_char_db; // int account_id -> struct online_char_data*
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data);
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
static void* create_online_char_data(DBKey key, va_list args)
{
@ -571,8 +571,8 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p, struct global_reg *reg,
*(str_p++) = '\t';
for(i = 0; i < MAX_SKILL; i++)
if (p->skill[i].id && p->skill[i].flag != 1) {
str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, (p->skill[i].flag == 0) ? p->skill[i].lv : p->skill[i].flag-2);
if (p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY) {
str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT) ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
}
*(str_p++) = '\t';
@ -1229,7 +1229,7 @@ void mmo_char_sync(void)
//----------------------------------------------------
// Function to save (in a periodic way) datas in files
//----------------------------------------------------
int mmo_char_sync_timer(int tid, unsigned int tick, int id, intptr data)
int mmo_char_sync_timer(int tid, unsigned int tick, int id, intptr_t data)
{
if (save_log)
ShowInfo("Saving all files...\n");
@ -1782,7 +1782,7 @@ int count_users(void)
int i, users;
users = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
if (server[i].fd > 0) {
users += server[i].users;
}
@ -2060,27 +2060,77 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
// continues when account data is received...
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void mapif_server_reset(int id);
/// Resets all the data.
void loginif_reset(void)
{
int id;
// TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
for( id = 0; id < ARRAYLENGTH(server); ++id )
mapif_server_reset(id);
flush_fifos();
exit(EXIT_FAILURE);
}
/// Checks the conditions for the server to stop.
/// If all the conditions are met, it stops the core loop.
void loginif_check_shutdown(void)
{
if( runflag != CHARSERVER_ST_SHUTDOWN )
return;
runflag = CORE_ST_STOP;
}
/// Called when the connection to Login Server is disconnected.
void loginif_on_disconnect(void)
{
ShowWarning("Connection to Login Server lost.\n\n");
}
/// Called when all the connection steps are completed.
void loginif_on_ready(void)
{
int i;
loginif_check_shutdown();
//Send online accounts to login server.
send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
if( i == ARRAYLENGTH(server) )
ShowStatus("Awaiting maps from map-server.\n");
}
int parse_fromlogin(int fd)
{
struct char_session_data* sd = NULL;
int i;
struct char_session_data *sd;
// only login-server can have an access to here.
// so, if it isn't the login-server, we disconnect the session.
// only process data from the login-server
if( fd != login_fd )
set_eof(fd);
if(session[fd]->flag.eof) {
if (fd == login_fd) {
ShowWarning("Connection to login-server lost (connection #%d).\n", fd);
login_fd = -1;
}
{
ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
do_close(fd);
return 0;
}
if( session[fd]->flag.eof )
{
do_close(fd);
login_fd = -1;
loginif_on_disconnect();
return 0;
}
sd = (struct char_session_data*)session[fd]->session_data;
while(RFIFOREST(fd) >= 2)
@ -2101,16 +2151,11 @@ int parse_fromlogin(int fd)
ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
ShowError("Also, please make sure your accounts file (default: accounts.txt) has the correct communication username/passwords and the gender of the account is S.\n");
ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
set_eof(fd);
return 0;
} else {
ShowStatus("Connected to login-server (connection #%d).\n", fd);
//Send online accounts to login server.
send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
if( i == MAX_MAP_SERVERS )
ShowStatus("Awaiting maps from map-server.\n");
loginif_on_ready();
}
RFIFOSKIP(fd,3);
break;
@ -2226,7 +2271,7 @@ int parse_fromlogin(int fd)
}
// remove specifical skills of classes 19, 4020 and 4042
for(j = 315; j <= 322; j++) {
if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) {
if (char_dat[i].status.skill[j].id > 0 && char_dat[i].status.skill[j].flag == SKILL_FLAG_PERMANENT) {
char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv;
char_dat[i].status.skill[j].id = 0;
char_dat[i].status.skill[j].lv = 0;
@ -2234,7 +2279,7 @@ int parse_fromlogin(int fd)
}
// remove specifical skills of classes 20, 4021 and 4043
for(j = 323; j <= 330; j++) {
if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) {
if (char_dat[i].status.skill[j].id > 0 && char_dat[i].status.skill[j].flag == SKILL_FLAG_PERMANENT) {
char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv;
char_dat[i].status.skill[j].id = 0;
char_dat[i].status.skill[j].lv = 0;
@ -2377,6 +2422,34 @@ int parse_fromlogin(int fd)
return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
int ping_login_server(int tid, unsigned int tick, int id, intptr_t data);
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void do_init_loginif(void)
{
// establish char-login connection if not present
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
// keep the char-login connection alive
add_timer_func_list(ping_login_server, "ping_login_server");
add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
// send a list of all online account IDs to login server
add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
}
void do_final_loginif(void)
{
if( login_fd != -1 )
{
do_close(login_fd);
login_fd = -1;
}
}
int request_accreg2(int account_id, int char_id)
{
if (login_fd > 0) {
@ -2592,36 +2665,76 @@ int char_loadName(int char_id, char* name)
int search_mapserver(unsigned short map, uint32 ip, uint16 port);
/// Initializes a server structure.
void mapif_server_init(int id)
{
memset(&server[id], 0, sizeof(server[id]));
server[id].fd = -1;
}
/// Destroys a server structure.
void mapif_server_destroy(int id)
{
if( server[id].fd == -1 )
{
do_close(server[id].fd);
server[id].fd = -1;
}
}
/// Resets all the data related to a server.
void mapif_server_reset(int id)
{
int i,j;
unsigned char buf[16384];
int fd = server[id].fd;
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
WBUFL(buf,4) = htonl(server[id].ip);
WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
WBUFW(buf,10+(j++)*4) = server[id].map[i];
if (j > 0) {
WBUFW(buf,2) = j * 4 + 10;
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
create_online_files();
mapif_server_destroy(id);
mapif_server_init(id);
}
/// Called when the connection to a Map Server is disconnected.
void mapif_on_disconnect(int id)
{
ShowStatus("Map-server #%d has disconnected.\n", id);
mapif_server_reset(id);
}
int parse_frommap(int fd)
{
int i, j;
int id;
ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
if(id == MAX_MAP_SERVERS)
set_eof(fd);
if(session[fd]->flag.eof) {
if (id < MAX_MAP_SERVERS) {
unsigned char buf[16384];
ShowStatus("Map-server %d (session #%d) has disconnected.\n", id, fd);
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
WBUFL(buf,4) = htonl(server[id].ip);
WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
WBUFW(buf,10+(j++)*4) = server[id].map[i];
if (j > 0) {
WBUFW(buf,2) = j * 4 + 10;
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
memset(&server[id], 0, sizeof(struct mmo_map_server));
server[id].fd = -1;
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
}
ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
if( id == ARRAYLENGTH(server) )
{// not a map server
ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
do_close(fd);
create_online_files();
return 0;
}
if( session[fd]->flag.eof )
{
do_close(fd);
server[id].fd = -1;
mapif_on_disconnect(id);
return 0;
}
@ -2672,14 +2785,14 @@ int parse_frommap(int fd)
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
// Transmitting the maps of the other map-servers to the new map-server
for(x = 0; x < MAX_MAP_SERVERS; x++) {
for(x = 0; x < ARRAYLENGTH(server); x++) {
if (server[x].fd > 0 && x != id) {
WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server));
WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(server[x].ip);
WFIFOW(fd,8) = htons(server[x].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
for(i = 0; i < ARRAYLENGTH(server); i++)
if (server[x].map[i])
WFIFOW(fd,10+(j++)*4) = server[x].map[i];
if (j > 0) {
@ -2802,26 +2915,37 @@ int parse_frommap(int fd)
uint32 ip = RFIFOL(fd,14);
RFIFOSKIP(fd,18);
// create temporary auth entry
CREATE(node, struct auth_node, 1);
node->account_id = account_id;
node->char_id = 0;
node->login_id1 = login_id1;
node->login_id2 = login_id2;
//node->sex = 0;
node->ip = ntohl(ip);
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
//node->gmlevel = 0;
idb_put(auth_db, account_id, node);
if( runflag != CHARSERVER_ST_RUNNING )
{
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 0;// not ok
WFIFOSET(fd,7);
}
else
{
// create temporary auth entry
CREATE(node, struct auth_node, 1);
node->account_id = account_id;
node->char_id = 0;
node->login_id1 = login_id1;
node->login_id2 = login_id2;
//node->sex = 0;
node->ip = ntohl(ip);
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
//node->gmlevel = 0;
idb_put(auth_db, account_id, node);
//Set char to "@ char select" in online db [Kevin]
set_char_charselect(account_id);
//Set char to "@ char select" in online db [Kevin]
set_char_charselect(account_id);
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 0;
WFIFOSET(fd,7);
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 1;// ok
WFIFOSET(fd,7);
}
}
break;
@ -2839,7 +2963,9 @@ int parse_frommap(int fd)
char_data = search_character(RFIFOL(fd,2), RFIFOL(fd,14));
if (map_fd >= 0 && session[map_fd] && char_data)
if( runflag == CHARSERVER_ST_RUNNING &&
session_isActive(map_fd) &&
char_data )
{ //Send the map server the auth of this player.
struct auth_node* node;
@ -3140,7 +3266,9 @@ int parse_frommap(int fd)
node = (struct auth_node*)idb_get(auth_db, account_id);
cd = search_character(account_id, char_id);
if( node != NULL && cd != NULL &&
if( runflag == CHARSERVER_ST_RUNNING &&
cd != NULL &&
node != NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 &&
@ -3204,13 +3332,27 @@ int parse_frommap(int fd)
return 0;
}
void do_init_mapif(void)
{
int i;
for( i = 0; i < ARRAYLENGTH(server); ++i )
mapif_server_init(i);
}
void do_final_mapif(void)
{
int i;
for( i = 0; i < ARRAYLENGTH(server); ++i )
mapif_server_destroy(i);
}
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
// If found, returns the server's index in the 'server' array (otherwise returns -1).
int search_mapserver(unsigned short map, uint32 ip, uint16 port)
{
int i, j;
for(i = 0; i < MAX_MAP_SERVERS; i++)
for(i = 0; i < ARRAYLENGTH(server); i++)
{
if (server[i].fd > 0
&& (ip == (uint32)-1 || server[i].ip == ip)
@ -3526,6 +3668,15 @@ int parse_char(int fd)
WFIFOL(fd,0) = account_id;
WFIFOSET(fd,4);
if( runflag != CHARSERVER_ST_RUNNING )
{
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x6c;
WFIFOB(fd,2) = 0;// rejected from server
WFIFOSET(fd,3);
break;
}
// search authentification
node = (struct auth_node*)idb_get(auth_db, account_id);
if( node != NULL &&
@ -3602,8 +3753,8 @@ int parse_char(int fd)
if (i < 0) {
unsigned short j;
//First check that there's actually a map server online.
ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
if (j == MAX_MAP_SERVERS) {
ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
if (j == ARRAYLENGTH(server)) {
ShowInfo("Connection Closed. No map servers available.\n");
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
@ -3927,8 +4078,12 @@ int parse_char(int fd)
char* l_pass = (char*)RFIFOP(fd,26);
l_user[23] = '\0';
l_pass[23] = '\0';
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
if( runflag != CHARSERVER_ST_RUNNING ||
i == ARRAYLENGTH(server) ||
strcmp(l_user, userid) != 0 ||
strcmp(l_pass, passwd) != 0 )
{
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2af9;
WFIFOB(fd,2) = 3;
@ -3991,7 +4146,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
int i, c;
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0) {
WFIFOHEAD(fd,len);
@ -4009,7 +4164,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
int i, c;
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0 && fd != sfd) {
WFIFOHEAD(fd,len);
@ -4027,8 +4182,8 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
int i;
if (fd >= 0) {
ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server[i].fd );
if( i < MAX_MAP_SERVERS )
ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
if( i < ARRAYLENGTH(server) )
{
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
@ -4039,7 +4194,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
return 0;
}
int broadcast_user_count(int tid, unsigned int tick, int id, intptr data)
int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
{
uint8 buf[6];
int users = count_users();
@ -4085,7 +4240,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
return 0;
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd])
{
@ -4103,7 +4258,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
return 0;
@ -4136,7 +4291,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
}
// sends a ping packet to login server (will receive pong 0x2718)
int ping_login_server(int tid, unsigned int tick, int id, intptr data)
int ping_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
{
@ -4151,7 +4306,7 @@ int ping_login_server(int tid, unsigned int tick, int id, intptr data)
//Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
//replies/disconnect the player we tried to kick. [Skotlex]
//------------------------------------------------
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data)
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
{
struct online_char_data* character;
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
@ -4175,7 +4330,7 @@ static int online_data_cleanup_sub(DBKey key, void *data, va_list ap)
return 0;
}
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr data)
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
online_char_db->foreach(online_char_db, online_data_cleanup_sub);
return 0;
@ -4431,12 +4586,16 @@ int char_config_read(const char *cfgName)
#ifndef TXT_SQL_CONVERT
void do_final(void)
{
ShowStatus("Terminating server.\n");
ShowStatus("Terminating...\n");
mmo_char_sync();
inter_save();
set_all_offline(-1);
flush_fifos();
do_final_mapif();
do_final_loginif();
// write online players files with no player
online_char_db->clear(online_char_db, NULL);
create_online_files();
@ -4445,11 +4604,12 @@ void do_final(void)
auth_db->destroy(auth_db, NULL);
if(char_dat) aFree(char_dat);
if (login_fd > 0)
do_close(login_fd);
if (char_fd > 0)
if( char_fd != -1 )
{
do_close(char_fd);
char_fd = -1;
}
#ifdef ENABLE_SC_SAVING
status_final();
@ -4458,6 +4618,7 @@ void do_final(void)
mapindex_final();
char_log("----End of char-server (normal end with closing of all files).\n");
ShowStatus("Finished.\n");
}
//------------------------------
@ -4473,15 +4634,27 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_CHAR;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
if( runflag != CHARSERVER_ST_SHUTDOWN )
{
int id;
runflag = CHARSERVER_ST_SHUTDOWN;
ShowStatus("Shutting down...\n");
// TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
for( id = 0; id < ARRAYLENGTH(server); ++id )
mapif_server_reset(id);
loginif_check_shutdown();
flush_fifos();
runflag = CORE_ST_STOP;
}
}
int do_init(int argc, char **argv)
{
int i;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
memset(&server[i], 0, sizeof(struct mmo_map_server));
server[i].fd = -1;
}
//Read map indexes
mapindex_init();
start_point.map = mapindex_name2id("new_zone01");
@ -4512,8 +4685,6 @@ int do_init(int argc, char **argv)
inter_init_txt((argc > 2) ? argv[2] : inter_cfgName); // inter server <20>‰Šú‰»
ShowInfo("char server initialized.\n");
set_defaultparse(parse_char);
if ((naddr_ != 0) && (!login_ip || !char_ip))
{
char ip_str[16];
@ -4533,22 +4704,13 @@ int do_init(int argc, char **argv)
}
}
// establish char-login connection if not present
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
// keep the char-login connection alive
add_timer_func_list(ping_login_server, "ping_login_server");
add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
do_init_loginif();
do_init_mapif();
// periodically update the overall user count on all mapservers + login server
add_timer_func_list(broadcast_user_count, "broadcast_user_count");
add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
// send a list of all online account IDs to login server
add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
// ???
add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
@ -4564,10 +4726,17 @@ int do_init(int argc, char **argv)
{
//##TODO invoke a CONSOLE_START plugin event
}
set_defaultparse(parse_char);
char_fd = make_listen_bind(bind_ip, char_port);
char_log("The char-server is ready (Server is listening on the port %d).\n", char_port);
ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
if( runflag != CORE_ST_STOP )
{
shutdown_callback = do_shutdown;
runflag = CHARSERVER_ST_RUNNING;
}
return 0;
}

View File

@ -4,8 +4,18 @@
#ifndef _CHAR_H_
#define _CHAR_H_
#include "../common/core.h" // CORE_ST_LAST
#include "../common/mmo.h"
#ifndef TXT_SQL_CONVERT
enum E_CHARSERVER_ST
{
CHARSERVER_ST_RUNNING = CORE_ST_LAST,
CHARSERVER_ST_SHUTDOWN,
CHARSERVER_ST_LAST
};
#endif
#define MAX_MAP_SERVERS 30
#define DEFAULT_AUTOSAVE_INTERVAL 300*1000

View File

@ -36,7 +36,7 @@ int inter_homun_tostr(char *str,struct s_homunculus *p)
for (i = 0; i < MAX_HOMUNSKILL; i++)
{
if (p->hskill[i].id && !p->hskill[i].flag)
if (p->hskill[i].id && p->hskill[i].flag == SKILL_FLAG_PERMANENT)
str+=sprintf(str,"%d,%d,", p->hskill[i].id, p->hskill[i].lv);
}

View File

@ -0,0 +1,57 @@
#
# char sql
#
if( HAVE_common_sql )
message( STATUS "Creating target char-server_sql" )
set( SQL_CHAR_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/char.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_auction.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_mail.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_mercenary.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_party.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_quest.h"
"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.h"
"${CMAKE_CURRENT_SOURCE_DIR}/inter.h"
)
set( SQL_CHAR_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/char.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_auction.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_mail.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_mercenary.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_party.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_quest.c"
"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.c"
"${CMAKE_CURRENT_SOURCE_DIR}/inter.c"
)
set( DEPENDENCIES common_sql )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
source_group( char FILES ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
include_directories( ${INCLUDE_DIRS} )
add_executable( char-server_sql ${SOURCE_FILES} )
add_dependencies( char-server_sql ${DEPENDENCIES} )
target_link_libraries( char-server_sql ${LIBRARIES} ${DEPENDENCIES} )
set_target_properties( char-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
if( WITH_COMPONENT_RUNTIME )
cpack_add_component( Runtime_charserver_sql DESCRIPTION "char-server (sql version)" DISPLAY_NAME "char-server_sql" GROUP Runtime )
install( TARGETS char-server_sql
DESTINATION "."
COMPONENT Runtime_charserver_sql )
endif()
message( STATUS "Creating target char-server_sql - done" )
set( HAVE_char-server_sql ON CACHE BOOL "char-server_sql target is available" )
mark_as_advanced( HAVE_char-server_sql )
else()
message( STATUS "Skipping target char-server_sql (requires common_sql)" )
unset( HAVE_char-server_sql CACHE )
endif()

View File

@ -3,12 +3,16 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/malloc.o ../common/obj_all/showmsg.o ../common/obj_all/utils.o \
../common/obj_all/strlib.o ../common/obj_all/grfio.o \
../common/obj_all/mapindex.o ../common/obj_all/ers.o
../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/random.o
COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
../common/malloc.h ../common/showmsg.h ../common/utils.h \
../common/strlib.h ../common/grfio.h \
../common/mapindex.h ../common/ers.h
../common/mapindex.h ../common/ers.h ../common/random.h
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_H = ../common/sql.h
@ -19,7 +23,7 @@ CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homu
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
CHAR_SERVER_SQL_DEPENDS=obj_sql $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ)
CHAR_SERVER_SQL_DEPENDS=obj_sql $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ)
else
CHAR_SERVER_SQL_DEPENDS=needs_mysql
endif
@ -32,7 +36,7 @@ endif
all: char-server_sql
char-server_sql: $(CHAR_SERVER_SQL_DEPENDS)
@CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @MYSQL_LIBS@
@CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @MYSQL_LIBS@
clean:
rm -rf *.o obj_sql ../../char-server_sql@EXEEXT@
@ -53,12 +57,15 @@ needs_mysql:
obj_sql:
-mkdir obj_sql
obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(COMMON_SQL_H)
@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(COMMON_SQL_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing common object files
# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common sql
../common/obj_sql/%.o:
@$(MAKE) -C ../common sql
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar

View File

@ -194,7 +194,7 @@ struct online_char_data {
};
static DBMap* online_char_db; // int account_id -> struct online_char_data*
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data);
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
static void* create_online_char_data(DBKey key, va_list args)
{
@ -590,11 +590,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
//insert here.
for( i = 0, count = 0; i < MAX_SKILL; ++i )
{
if(p->skill[i].id && p->skill[i].flag!=1)
if(p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY)
{
if( count )
StringBuf_AppendStr(&buf, ",");
StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == 0 ? p->skill[i].lv : p->skill[i].flag - 2));
StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0));
++count;
}
}
@ -1107,7 +1107,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_skill.lv, 0, NULL, NULL) )
SqlStmt_ShowDebug(stmt);
tmp_skill.flag = 0;
tmp_skill.flag = SKILL_FLAG_PERMANENT;
for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
@ -1543,7 +1543,7 @@ int count_users(void)
int i, users;
users = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
if (server[i].fd > 0) {
users += server[i].users;
}
@ -1778,27 +1778,78 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
// continues when account data is received...
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void mapif_server_reset(int id);
/// Resets all the data.
void loginif_reset(void)
{
int id;
// TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
for( id = 0; id < ARRAYLENGTH(server); ++id )
mapif_server_reset(id);
flush_fifos();
exit(EXIT_FAILURE);
}
/// Checks the conditions for the server to stop.
/// Releases the cookie when all characters are saved.
/// If all the conditions are met, it stops the core loop.
void loginif_check_shutdown(void)
{
if( runflag != CHARSERVER_ST_SHUTDOWN )
return;
runflag = CORE_ST_STOP;
}
/// Called when the connection to Login Server is disconnected.
void loginif_on_disconnect(void)
{
ShowWarning("Connection to Login Server lost.\n\n");
}
/// Called when all the connection steps are completed.
void loginif_on_ready(void)
{
int i;
loginif_check_shutdown();
//Send online accounts to login server.
send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
if( i == ARRAYLENGTH(server) )
ShowStatus("Awaiting maps from map-server.\n");
}
int parse_fromlogin(int fd)
{
struct char_session_data* sd = NULL;
int i;
struct char_session_data *sd;
// only login-server can have an access to here.
// so, if it isn't the login-server, we disconnect the session.
// only process data from the login-server
if( fd != login_fd )
set_eof(fd);
if(session[fd]->flag.eof) {
if (fd == login_fd) {
ShowWarning("Connection to login-server lost (connection #%d).\n", fd);
login_fd = -1;
}
{
ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
do_close(fd);
return 0;
}
if( session[fd]->flag.eof )
{
do_close(fd);
login_fd = -1;
loginif_on_disconnect();
return 0;
}
sd = (struct char_session_data*)session[fd]->session_data;
while(RFIFOREST(fd) >= 2)
@ -1819,16 +1870,11 @@ int parse_fromlogin(int fd)
ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n");
ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
set_eof(fd);
return 0;
} else {
ShowStatus("Connected to login-server (connection #%d).\n", fd);
//Send online accounts to login server.
send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
if( i == MAX_MAP_SERVERS )
ShowStatus("Awaiting maps from map-server.\n");
loginif_on_ready();
}
RFIFOSKIP(fd,3);
break;
@ -2096,6 +2142,34 @@ int parse_fromlogin(int fd)
return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
int ping_login_server(int tid, unsigned int tick, int id, intptr_t data);
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void do_init_loginif(void)
{
// establish char-login connection if not present
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
// keep the char-login connection alive
add_timer_func_list(ping_login_server, "ping_login_server");
add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
// send a list of all online account IDs to login server
add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
}
void do_final_loginif(void)
{
if( login_fd != -1 )
{
do_close(login_fd);
login_fd = -1;
}
}
int request_accreg2(int account_id, int char_id)
{
if (login_fd > 0) {
@ -2252,39 +2326,79 @@ int char_loadName(int char_id, char* name)
int search_mapserver(unsigned short map, uint32 ip, uint16 port);
/// Initializes a server structure.
void mapif_server_init(int id)
{
memset(&server[id], 0, sizeof(server[id]));
server[id].fd = -1;
}
/// Destroys a server structure.
void mapif_server_destroy(int id)
{
if( server[id].fd == -1 )
{
do_close(server[id].fd);
server[id].fd = -1;
}
}
/// Resets all the data related to a server.
void mapif_server_reset(int id)
{
int i,j;
unsigned char buf[16384];
int fd = server[id].fd;
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
WBUFL(buf,4) = htonl(server[id].ip);
WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
WBUFW(buf,10+(j++)*4) = server[id].map[i];
if (j > 0) {
WBUFW(buf,2) = j * 4 + 10;
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server[id].fd) )
Sql_ShowDebug(sql_handle);
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
mapif_server_destroy(id);
mapif_server_init(id);
}
/// Called when the connection to a Map Server is disconnected.
void mapif_on_disconnect(int id)
{
ShowStatus("Map-server #%d has disconnected.\n", id);
mapif_server_reset(id);
}
int parse_frommap(int fd)
{
int i, j;
int id;
ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
if(id == MAX_MAP_SERVERS)
set_eof(fd);
if(session[fd]->flag.eof) {
if (id < MAX_MAP_SERVERS) {
unsigned char buf[16384];
ShowStatus("Map-server %d (session #%d) has disconnected.\n", id, fd);
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
WBUFL(buf,4) = htonl(server[id].ip);
WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
WBUFW(buf,10+(j++)*4) = server[id].map[i];
if (j > 0) {
WBUFW(buf,2) = j * 4 + 10;
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
memset(&server[id], 0, sizeof(struct mmo_map_server));
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server[id].fd) )
Sql_ShowDebug(sql_handle);
server[id].fd = -1;
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
}
ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
if( id == ARRAYLENGTH(server) )
{// not a map server
ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
do_close(fd);
return 0;
}
if( session[fd]->flag.eof )
{
do_close(fd);
server[id].fd = -1;
mapif_on_disconnect(id);
return 0;
}
while(RFIFOREST(fd) >= 2)
{
@ -2330,14 +2444,14 @@ int parse_frommap(int fd)
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
// Transmitting the maps of the other map-servers to the new map-server
for(x = 0; x < MAX_MAP_SERVERS; x++) {
for(x = 0; x < ARRAYLENGTH(server); x++) {
if (server[x].fd > 0 && x != id) {
WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server));
WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(server[x].ip);
WFIFOW(fd,8) = htons(server[x].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
for(i = 0; i < ARRAYLENGTH(server); i++)
if (server[x].map[i])
WFIFOW(fd,10+(j++)*4) = server[x].map[i];
if (j > 0) {
@ -2491,27 +2605,38 @@ int parse_frommap(int fd)
uint32 login_id2 = RFIFOL(fd,10);
uint32 ip = RFIFOL(fd,14);
RFIFOSKIP(fd,18);
if( runflag != CHARSERVER_ST_RUNNING )
{
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 0;// not ok
WFIFOSET(fd,7);
}
else
{
// create temporary auth entry
CREATE(node, struct auth_node, 1);
node->account_id = account_id;
node->char_id = 0;
node->login_id1 = login_id1;
node->login_id2 = login_id2;
//node->sex = 0;
node->ip = ntohl(ip);
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
//node->gmlevel = 0;
idb_put(auth_db, account_id, node);
// create temporary auth entry
CREATE(node, struct auth_node, 1);
node->account_id = account_id;
node->char_id = 0;
node->login_id1 = login_id1;
node->login_id2 = login_id2;
//node->sex = 0;
node->ip = ntohl(ip);
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
//node->gmlevel = 0;
idb_put(auth_db, account_id, node);
//Set char to "@ char select" in online db [Kevin]
set_char_charselect(account_id);
//Set char to "@ char select" in online db [Kevin]
set_char_charselect(account_id);
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 0;
WFIFOSET(fd,7);
WFIFOHEAD(fd,7);
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = account_id;
WFIFOB(fd,6) = 1;// ok
WFIFOSET(fd,7);
}
}
break;
@ -2534,8 +2659,10 @@ int parse_frommap(int fd)
mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
}
if (map_fd >= 0 && session[map_fd] && char_data)
if( runflag == CHARSERVER_ST_RUNNING &&
session_isActive(map_fd) &&
char_data )
{ //Send the map server the auth of this player.
struct auth_node* node;
@ -2879,7 +3006,9 @@ int parse_frommap(int fd)
mmo_char_fromsql(char_id, &char_dat, true);
cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
}
if( node != NULL && cd != NULL &&
if( runflag == CHARSERVER_ST_RUNNING &&
cd != NULL &&
node != NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 &&
@ -2942,13 +3071,27 @@ int parse_frommap(int fd)
return 0;
}
void do_init_mapif(void)
{
int i;
for( i = 0; i < ARRAYLENGTH(server); ++i )
mapif_server_init(i);
}
void do_final_mapif(void)
{
int i;
for( i = 0; i < ARRAYLENGTH(server); ++i )
mapif_server_destroy(i);
}
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
// If found, returns the server's index in the 'server' array (otherwise returns -1).
int search_mapserver(unsigned short map, uint32 ip, uint16 port)
{
int i, j;
for(i = 0; i < MAX_MAP_SERVERS; i++)
for(i = 0; i < ARRAYLENGTH(server); i++)
{
if (server[i].fd > 0
&& (ip == (uint32)-1 || server[i].ip == ip)
@ -3276,6 +3419,15 @@ int parse_char(int fd)
WFIFOL(fd,0) = account_id;
WFIFOSET(fd,4);
if( runflag != CHARSERVER_ST_RUNNING )
{
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x6c;
WFIFOB(fd,2) = 0;// rejected from server
WFIFOSET(fd,3);
break;
}
// search authentification
node = (struct auth_node*)idb_get(auth_db, account_id);
if( node != NULL &&
@ -3361,8 +3513,8 @@ int parse_char(int fd)
if (i < 0) {
unsigned short j;
//First check that there's actually a map server online.
ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
if (j == MAX_MAP_SERVERS) {
ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
if (j == ARRAYLENGTH(server)) {
ShowInfo("Connection Closed. No map servers available.\n");
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
@ -3665,8 +3817,12 @@ int parse_char(int fd)
char* l_pass = (char*)RFIFOP(fd,26);
l_user[23] = '\0';
l_pass[23] = '\0';
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
if( runflag != CHARSERVER_ST_RUNNING ||
i == ARRAYLENGTH(server) ||
strcmp(l_user, userid) != 0 ||
strcmp(l_pass, passwd) != 0 )
{
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2af9;
WFIFOB(fd,2) = 3;
@ -3729,7 +3885,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
int i, c;
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0) {
WFIFOHEAD(fd,len);
@ -3747,7 +3903,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
int i, c;
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0 && fd != sfd) {
WFIFOHEAD(fd,len);
@ -3765,8 +3921,8 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
int i;
if (fd >= 0) {
ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server[i].fd );
if( i < MAX_MAP_SERVERS )
ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
if( i < ARRAYLENGTH(server) )
{
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
@ -3777,7 +3933,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
return 0;
}
int broadcast_user_count(int tid, unsigned int tick, int id, intptr data)
int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
{
uint8 buf[6];
int users = count_users();
@ -3820,7 +3976,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
return 0;
}
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd])
{
@ -3838,7 +3994,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
return 0;
}
int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
return 0;
@ -3871,7 +4027,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
}
// sends a ping packet to login server (will receive pong 0x2718)
int ping_login_server(int tid, unsigned int tick, int id, intptr data)
int ping_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
{
@ -3886,7 +4042,7 @@ int ping_login_server(int tid, unsigned int tick, int id, intptr data)
//Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
//replies/disconnect the player we tried to kick. [Skotlex]
//------------------------------------------------
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data)
static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
{
struct online_char_data* character;
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
@ -3910,7 +4066,7 @@ static int online_data_cleanup_sub(DBKey key, void *data, va_list ap)
return 0;
}
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr data)
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
online_char_db->foreach(online_char_db, online_data_cleanup_sub);
return 0;
@ -4211,7 +4367,7 @@ int char_config_read(const char* cfgName)
void do_final(void)
{
ShowStatus("Terminating server.\n");
ShowStatus("Terminating...\n");
set_all_offline(-1);
set_all_offline_sql();
@ -4219,6 +4375,9 @@ void do_final(void)
inter_final();
flush_fifos();
do_final_mapif();
do_final_loginif();
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo`") )
Sql_ShowDebug(sql_handle);
@ -4227,13 +4386,16 @@ void do_final(void)
online_char_db->destroy(online_char_db, NULL);
auth_db->destroy(auth_db, NULL);
if (login_fd > 0)
do_close(login_fd);
if (char_fd > 0)
if( char_fd != -1 )
{
do_close(char_fd);
char_fd = -1;
}
Sql_Free(sql_handle);
mapindex_final();
ShowStatus("Finished.\n");
}
//------------------------------
@ -4249,15 +4411,27 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_CHAR;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
if( runflag != CHARSERVER_ST_SHUTDOWN )
{
int id;
runflag = CHARSERVER_ST_SHUTDOWN;
ShowStatus("Shutting down...\n");
// TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
for( id = 0; id < ARRAYLENGTH(server); ++id )
mapif_server_reset(id);
loginif_check_shutdown();
flush_fifos();
runflag = CORE_ST_STOP;
}
}
int do_init(int argc, char **argv)
{
int i;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
memset(&server[i], 0, sizeof(struct mmo_map_server));
server[i].fd = -1;
}
//Read map indexes
mapindex_init();
start_point.map = mapindex_name2id("new_zone01");
@ -4284,8 +4458,6 @@ int do_init(int argc, char **argv)
char_read_fame_list(); //Read fame lists.
ShowInfo("char server initialized.\n");
set_defaultparse(parse_char);
if ((naddr_ != 0) && (!login_ip || !char_ip))
{
char ip_str[16];
@ -4305,22 +4477,13 @@ int do_init(int argc, char **argv)
}
}
// establish char-login connection if not present
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
// keep the char-login connection alive
add_timer_func_list(ping_login_server, "ping_login_server");
add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
do_init_loginif();
do_init_mapif();
// periodically update the overall user count on all mapservers + login server
add_timer_func_list(broadcast_user_count, "broadcast_user_count");
add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
// send a list of all online account IDs to login server
add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
// ???
add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
@ -4351,9 +4514,16 @@ int do_init(int argc, char **argv)
ShowInfo("End of char server initilization function.\n");
set_defaultparse(parse_char);
ShowInfo("open port %d.....\n",char_port);
char_fd = make_listen_bind(bind_ip, char_port);
ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
if( runflag != CORE_ST_STOP )
{
shutdown_callback = do_shutdown;
runflag = CHARSERVER_ST_RUNNING;
}
return 0;
}

View File

@ -4,6 +4,17 @@
#ifndef _CHAR_SQL_H_
#define _CHAR_SQL_H_
#include "../common/core.h" // CORE_ST_LAST
#ifndef TXT_SQL_CONVERT
enum E_CHARSERVER_ST
{
CHARSERVER_ST_RUNNING = CORE_ST_LAST,
CHARSERVER_ST_SHUTDOWN,
CHARSERVER_ST_LAST
};
#endif
struct mmo_charstatus;
#define MAX_MAP_SERVERS 30

View File

@ -21,7 +21,7 @@
static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data*
void auction_delete(struct auction_data *auction);
static int auction_end_timer(int tid, unsigned int tick, int id, intptr data);
static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data);
static int auction_count(int char_id, bool buy)
{
@ -136,7 +136,7 @@ static void mapif_Auction_message(int char_id, unsigned char result)
mapif_sendall(buf,7);
}
static int auction_end_timer(int tid, unsigned int tick, int id, intptr data)
static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct auction_data *auction;
if( (auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL )

View File

@ -47,7 +47,7 @@ int mapif_guild_info(int fd,struct guild *g);
int guild_break_sub(int key,void *data,va_list ap);
int inter_guild_tosql(struct guild *g,int flag);
static int guild_save_timer(int tid, unsigned int tick, int id, intptr data)
static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data)
{
static int last_id = 0; //To know in which guild we were.
int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving.

144
src/common/CMakeLists.txt Normal file
View File

@ -0,0 +1,144 @@
#
# Create svnversion.h
#
message( STATUS "Creating svnversion.h" )
if( SVNVERSION )
file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h
"#ifndef SVNVERSION\n#define SVNVERSION ${SVNVERSION}\n#endif\n" )
else()
file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h "" )
endif()
set( GLOBAL_INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "" )
set( SVNVERSION ${SVNVERSION}
CACHE STRING "SVN version of the source code" )
if( WITH_COMPONENT_DEVELOPMENT )
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h
DESTINATION "src/common"
COMPONENT Development_base )
endif()
message( STATUS "Creating svnversion.h - done" )
#####################################################################
# setup
#
set( COMMON_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
CACHE PATH "common source directory" )
mark_as_advanced( COMMON_SOURCE_DIR )
set( COMMON_ALL_HEADERS
"${CMAKE_CURRENT_BINARY_DIR}/svnversion.h"
"${COMMON_SOURCE_DIR}/cbasetypes.h"
"${COMMON_SOURCE_DIR}/mmo.h"
"${COMMON_SOURCE_DIR}/plugin.h"
"${COMMON_SOURCE_DIR}/version.h"
)
set( COMMON_MINI_HEADERS
${COMMON_ALL_HEADERS}
"${COMMON_SOURCE_DIR}/core.h"
"${COMMON_SOURCE_DIR}/malloc.h"
"${COMMON_SOURCE_DIR}/showmsg.h"
"${COMMON_SOURCE_DIR}/strlib.h"
CACHE INTERNAL "" )
set( COMMON_MINI_SOURCES
"${COMMON_SOURCE_DIR}/core.c"
"${COMMON_SOURCE_DIR}/malloc.c"
"${COMMON_SOURCE_DIR}/showmsg.c"
"${COMMON_SOURCE_DIR}/strlib.c"
CACHE INTERNAL "" )
set( COMMON_MINI_DEFINITIONS MINICORE CACHE INTERNAL "" )
#
# common_base
#
if( WITH_ZLIB )
message( STATUS "Creating target common_base" )
set( COMMON_BASE_HEADERS
${COMMON_ALL_HEADERS}
"${COMMON_SOURCE_DIR}/core.h"
"${COMMON_SOURCE_DIR}/db.h"
"${COMMON_SOURCE_DIR}/ers.h"
"${COMMON_SOURCE_DIR}/grfio.h"
"${COMMON_SOURCE_DIR}/lock.h"
"${COMMON_SOURCE_DIR}/malloc.h"
"${COMMON_SOURCE_DIR}/mapindex.h"
"${COMMON_SOURCE_DIR}/md5calc.h"
"${COMMON_SOURCE_DIR}/nullpo.h"
"${COMMON_SOURCE_DIR}/plugins.h"
"${COMMON_SOURCE_DIR}/random.h"
"${COMMON_SOURCE_DIR}/showmsg.h"
"${COMMON_SOURCE_DIR}/socket.h"
"${COMMON_SOURCE_DIR}/strlib.h"
"${COMMON_SOURCE_DIR}/timer.h"
"${COMMON_SOURCE_DIR}/utils.h"
CACHE INTERNAL "common_base headers" )
set( COMMON_BASE_SOURCES
"${COMMON_SOURCE_DIR}/core.c"
"${COMMON_SOURCE_DIR}/db.c"
"${COMMON_SOURCE_DIR}/ers.c"
"${COMMON_SOURCE_DIR}/grfio.c"
"${COMMON_SOURCE_DIR}/lock.c"
"${COMMON_SOURCE_DIR}/malloc.c"
"${COMMON_SOURCE_DIR}/mapindex.c"
"${COMMON_SOURCE_DIR}/md5calc.c"
"${COMMON_SOURCE_DIR}/nullpo.c"
"${COMMON_SOURCE_DIR}/plugins.c"
"${COMMON_SOURCE_DIR}/random.c"
"${COMMON_SOURCE_DIR}/showmsg.c"
"${COMMON_SOURCE_DIR}/socket.c"
"${COMMON_SOURCE_DIR}/strlib.c"
"${COMMON_SOURCE_DIR}/timer.c"
"${COMMON_SOURCE_DIR}/utils.c"
CACHE INTERNAL "common_base sources" )
set( LIBRARIES ${ZLIB_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MT19937AR_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
set( SOURCE_FILES ${MT19937AR_HEADERS} ${MT19937AR_SOURCES} ${COMMON_BASE_HEADERS} ${COMMON_BASE_SOURCES} )
source_group( mt19937ar FILES ${MT19937AR_HEADERS} ${MT19937AR_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_BASE_SOURCES} )
add_library( common_base ${SOURCE_FILES} )
target_link_libraries( common_base ${LIBRARIES} )
set_target_properties( common_base PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
include_directories( ${INCLUDE_DIRS} )
message( STATUS "Creating target common_base - done" )
set( HAVE_common_base ON CACHE BOOL "common_base target is available" )
mark_as_advanced( HAVE_common_base )
else()
message( STATUS "Skipping target common_base (requires ZLIB)" )
unset( HAVE_common_base CACHE )
endif()
#
# common_sql
#
if( HAVE_common_base AND WITH_MYSQL )
message( STATUS "Creating target common_sql" )
set( COMMON_SQL_HEADERS
${COMMON_ALL_HEADERS}
"${CMAKE_CURRENT_SOURCE_DIR}/sql.h"
CACHE INTERNAL "common_sql headers" )
set( COMMON_SQL_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/sql.c"
CACHE INTERNAL "common_sql sources" )
set( DEPENDENCIES common_base )
set( LIBRARIES ${MYSQL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MYSQL_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
set( SOURCE_FILES ${COMMON_SQL_HEADERS} ${COMMON_SQL_SOURCES} )
source_group( common FILES ${COMMON_SQL_HEADERS} ${COMMON_SQL_SOURCES} )
add_library( common_sql ${SOURCE_FILES} )
add_dependencies( common_sql ${DEPENDENCIES} )
target_link_libraries( common_sql ${LIBRARIES} ${DEPENDENCIES} )
set_target_properties( common_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
include_directories( ${INCLUDE_DIRS} )
message( STATUS "Creating target common_sql - done" )
set( HAVE_common_sql ON CACHE BOOL "common_sql target is available" )
mark_as_advanced( HAVE_common_sql )
else()
message( STATUS "Skipping target common_sql (requires common_base and MYSQL)" )
unset( HAVE_common_sql CACHE )
endif()

View File

@ -2,15 +2,19 @@
COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o obj_all/plugins.o obj_all/lock.o \
obj_all/nullpo.o obj_all/malloc.o obj_all/showmsg.o obj_all/strlib.o obj_all/utils.o \
obj_all/grfio.o obj_all/mapindex.o obj_all/ers.o obj_all/md5calc.o \
obj_all/minicore.o obj_all/minisocket.o obj_all/minimalloc.o
obj_all/minicore.o obj_all/minisocket.o obj_all/minimalloc.o obj_all/random.o
COMMON_H = svnversion.h mmo.h plugin.h version.h \
core.h socket.h timer.h db.h plugins.h lock.h \
nullpo.h malloc.h showmsg.h strlib.h utils.h \
grfio.h mapindex.h ers.h md5calc.h
grfio.h mapindex.h ers.h md5calc.h random.h
COMMON_SQL_OBJ = obj_sql/sql.o
COMMON_SQL_H = sql.h
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
ALL_DEPENDS=txt sql
@ -19,6 +23,7 @@ else
ALL_TARGET=txt
SQL_DEPENDS=needs_mysql
endif
TXT_DEPENDS=common
@SET_MAKE@
@ -27,7 +32,7 @@ endif
all: $(ALL_DEPENDS)
txt: common
txt: $(TXT_DEPENDS)
sql: $(SQL_DEPENDS)
@ -54,16 +59,16 @@ obj_all:
obj_sql:
-mkdir obj_sql
common: obj_all $(COMMON_OBJ)
common: obj_all $(COMMON_OBJ) $(MT19937AR_OBJ)
common_sql: obj_sql $(COMMON_SQL_OBJ)
obj_all/%.o: %.c $(COMMON_H)
@CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_all/%.o: %.c $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_all/mini%.o: %.c $(COMMON_H)
@CC@ @CFLAGS@ -DMINICORE @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_all/mini%.o: %.c $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DMINICORE @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(COMMON_H) $(COMMON_SQL_H)
@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
@ -80,3 +85,7 @@ else
svnversion.h:
@printf "\n" > svnversion.h
endif
# missing object files
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar

View File

@ -78,14 +78,9 @@
// NOTE: Visual C++ uses <inttypes.h> and <stdint.h> provided in /3rdparty
//////////////////////////////////////////////////////////////////////////
#include <inttypes.h>
//////////////////////////////////////////////////////////////////////////
// typedefs to compensate type size change from 32bit to 64bit
// MS implements LLP64 model, normal unix does LP64,
// only Silicon Graphics/Cray goes ILP64 so don't care (and don't support)
//////////////////////////////////////////////////////////////////////////
#include <stdint.h>
#include <limits.h>
// ILP64 isn't supported, so always 32 bits?
#ifndef UINT_MAX
#define UINT_MAX 0xffffffff
@ -95,49 +90,56 @@
// Integers with guaranteed _exact_ size.
//////////////////////////////////////////////////////////////////////////
#define SIZEOF_LONG 4
#define SIZEOF_INT 4
#define HAVE_INT_8_16_32
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef char int8;
typedef short int16;
typedef int int32;
typedef int8_t sint8;
typedef int16_t sint16;
typedef int32_t sint32;
typedef int64_t sint64;
typedef signed char sint8;
typedef signed short sint16;
typedef signed int sint32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
#undef UINT8_MIN
#undef UINT16_MIN
#undef UINT32_MIN
#define UINT8_MIN ((uint8) 0)
#define UINT16_MIN ((uint16)0)
#define UINT32_MIN ((uint32)0)
#undef UINT64_MIN
#define UINT8_MIN ((uint8) UINT8_C(0x00))
#define UINT16_MIN ((uint16)UINT16_C(0x0000))
#define UINT32_MIN ((uint32)UINT32_C(0x00000000))
#define UINT64_MIN ((uint64)UINT64_C(0x0000000000000000))
#undef UINT8_MAX
#undef UINT16_MAX
#undef UINT32_MAX
#define UINT8_MAX ((uint8) 0xFF)
#define UINT16_MAX ((uint16)0xFFFF)
#define UINT32_MAX ((uint32)0xFFFFFFFF)
#undef UINT64_MAX
#define UINT8_MAX ((uint8) UINT8_C(0xFF))
#define UINT16_MAX ((uint16)UINT16_C(0xFFFF))
#define UINT32_MAX ((uint32)UINT32_C(0xFFFFFFFF))
#define UINT64_MAX ((uint64)UINT64_C(0xFFFFFFFFFFFFFFFF))
#undef SINT8_MIN
#undef SINT16_MIN
#undef SINT32_MIN
#define SINT8_MIN ((sint8) 0x80)
#define SINT16_MIN ((sint16)0x8000)
#define SINT32_MIN ((sint32)0x80000000)
#undef SINT64_MIN
#define SINT8_MIN ((sint8) INT8_C(0x80))
#define SINT16_MIN ((sint16)INT16_C(0x8000))
#define SINT32_MIN ((sint32)INT32_C(0x80000000))
#define SINT64_MIN ((sint32)INT64_C(0x8000000000000000))
#undef SINT8_MAX
#undef SINT16_MAX
#undef SINT32_MAX
#define SINT8_MAX ((sint8) 0x7F)
#define SINT16_MAX ((sint16)0x7FFF)
#define SINT32_MAX ((sint32)0x7FFFFFFF)
#undef SINT64_MAX
#define SINT8_MAX ((sint8) INT8_C(0x7F))
#define SINT16_MAX ((sint16)INT16_C(0x7FFF))
#define SINT32_MAX ((sint32)INT32_C(0x7FFFFFFF))
#define SINT64_MAX ((sint64)INT64_C(0x7FFFFFFFFFFFFFFF))
//////////////////////////////////////////////////////////////////////////
// Integers with guaranteed _minimum_ size.
@ -172,52 +174,11 @@ typedef int ssize_t;
//////////////////////////////
//////////////////////////////////////////////////////////////////////////
// portable 64-bit integers
//////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 int64;
typedef signed __int64 sint64;
typedef unsigned __int64 uint64;
#else
typedef long long int64;
typedef signed long long sint64;
typedef unsigned long long uint64;
#endif
#ifndef INT64_MIN
#define INT64_MIN (INT64_C(-9223372036854775807)-1)
#endif
#ifndef INT64_MAX
#define INT64_MAX (INT64_C(9223372036854775807))
#endif
#ifndef UINT64_MAX
#define UINT64_MAX (UINT64_C(18446744073709551615))
#endif
//////////////////////////////////////////////////////////////////////////
// pointer sized integers
//////////////////////////////////////////////////////////////////////////
#undef UINTPTR_MIN
#undef UINTPTR_MAX
#undef INTPTR_MIN
#undef INTPTR_MAX
#ifdef __64BIT__
typedef uint64 uintptr;
typedef int64 intptr;
#define UINTPTR_MIN UINT64_MIN
#define UINTPTR_MAX UINT64_MAX
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#else
typedef uint32 uintptr;
typedef int32 intptr;
#define UINTPTR_MIN UINT32_MIN
#define UINTPTR_MAX UINT32_MAX
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#endif
typedef intptr_t intptr;
typedef uintptr_t uintptr;
//////////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,12 @@
#include <unistd.h>
#endif
int runflag = 1;
/// Called when a terminate signal is received.
void (*shutdown_callback)(void) = NULL;
int runflag = CORE_ST_RUN;
int arg_c = 0;
char **arg_v = NULL;
@ -78,7 +83,10 @@ static void sig_proc(int sn)
case SIGTERM:
if (++is_called > 3)
exit(EXIT_SUCCESS);
runflag = 0;
if( shutdown_callback != NULL )
shutdown_callback();
else
runflag = CORE_ST_STOP;// auto-shutdown
break;
case SIGSEGV:
case SIGFPE:
@ -249,7 +257,7 @@ int main (int argc, char **argv)
{// Main runtime cycle
int next;
while (runflag) {
while (runflag != CORE_ST_STOP) {
next = do_timer(gettick_nocache());
do_sockets(next);
}

View File

@ -7,6 +7,7 @@
extern int arg_c;
extern char **arg_v;
/// @see E_CORE_ST
extern int runflag;
extern char *SERVER_NAME;
extern char SERVER_TYPE;
@ -18,4 +19,16 @@ extern void set_server_type(void);
extern void do_abort(void);
extern void do_final(void);
/// The main loop continues until runflag is CORE_ST_STOP
enum E_CORE_ST
{
CORE_ST_STOP = 0,
CORE_ST_RUN,
CORE_ST_LAST
};
/// Called when a terminate signal is received. (Ctrl+C pressed)
/// If NULL, runflag is set to CORE_ST_STOP instead.
extern void (*shutdown_callback)(void);
#endif /* _CORE_H_ */

View File

@ -67,13 +67,13 @@
\*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "db.h"
#include "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/showmsg.h"
#include "../common/ers.h"
#include "../common/strlib.h"
/*****************************************************************************\
* (1) Private typedefs, enums, structures, defines and global variables of *
@ -271,6 +271,7 @@ static struct db_stats {
uint32 dbit_remove;
uint32 dbit_destroy;
uint32 db_iterator;
uint32 db_exists;
uint32 db_get;
uint32 db_getall;
uint32 db_vgetall;
@ -304,7 +305,7 @@ static struct db_stats {
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
};
#define DB_COUNTSTAT(token) if (stats. ## token != UINT32_MAX) ++stats. ## token
#else /* !defined(DB_ENABLE_STATS) */
@ -630,19 +631,17 @@ static int db_is_key_null(DBType type, DBKey key)
static DBKey db_dup_key(DBMap_impl* db, DBKey key)
{
char *str;
size_t len;
DB_COUNTSTAT(db_dup_key);
switch (db->type) {
case DB_STRING:
case DB_ISTRING:
if (db->maxlen) {
CREATE(str, char, db->maxlen +1);
strncpy(str, key.str, db->maxlen);
str[db->maxlen] = '\0';
key.str = str;
} else {
key.str = (char *)aStrdup(key.str);
}
len = strnlen(key.str, db->maxlen);
str = (char*)aMalloc(len + 1);
memcpy(str, key.str, len);
str[len] = '\0';
key.str = str;
return key;
default:
@ -888,8 +887,6 @@ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
DB_COUNTSTAT(db_string_cmp);
if (maxlen == 0)
maxlen = UINT16_MAX;
return strncmp((const char *)key1.str, (const char *)key2.str, maxlen);
}
@ -908,8 +905,6 @@ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
{
DB_COUNTSTAT(db_istring_cmp);
if (maxlen == 0)
maxlen = UINT16_MAX;
return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
}
@ -951,7 +946,6 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
/**
* Default hasher for DB_STRING databases.
* If maxlen if 0, the maximum number of maxlen is used instead.
* @param key Key to be hashed
* @param maxlen Maximum length of the key to hash
* @return hash of the key
@ -966,8 +960,6 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
unsigned short i;
DB_COUNTSTAT(db_string_hash);
if (maxlen == 0)
maxlen = UINT16_MAX;
for (i = 0; *k; ++i) {
hash = (hash*33 + ((unsigned char)*k))^(hash>>24);
@ -981,7 +973,6 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
/**
* Default hasher for DB_ISTRING databases.
* If maxlen if 0, the maximum number of maxlen is used instead.
* @param key Key to be hashed
* @param maxlen Maximum length of the key to hash
* @return hash of the key
@ -995,8 +986,6 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
unsigned short i;
DB_COUNTSTAT(db_istring_hash);
if (maxlen == 0)
maxlen = UINT16_MAX;
for (i = 0; *k; i++) {
hash = (hash*33 + ((unsigned char)TOLOWER(*k)))^(hash>>24);
@ -1087,6 +1076,7 @@ static void db_release_both(DBKey key, void *data, DBRelease which)
* dbit_obj_destroy - Destroys the iterator, unlocking the database and *
* freeing used memory. *
* db_obj_iterator - Return a new databse iterator. *
* db_obj_exists - Checks if an entry exists. *
* db_obj_get - Get the data identified by the key. *
* db_obj_vgetall - Get the data of the matched entries. *
* db_obj_getall - Get the data of the matched entries. *
@ -1401,6 +1391,57 @@ static DBIterator* db_obj_iterator(DBMap* self)
return &it->vtable;
}
/**
* Returns true if the entry exists.
* @param self Interface of the database
* @param key Key that identifies the entry
* @return true is the entry exists
* @protected
* @see DBMap#exists
*/
static bool db_obj_exists(DBMap* self, DBKey key)
{
DBMap_impl* db = (DBMap_impl*)self;
DBNode node;
int c;
bool found = false;
DB_COUNTSTAT(db_exists);
if (db == NULL) return false; // nullpo candidate
if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
return false; // nullpo candidate
}
if (db->cache && db->cmp(key, db->cache->key, db->maxlen) == 0) {
#if defined(DEBUG)
if (db->cache->deleted) {
ShowDebug("db_exists: Cache contains a deleted node. Please report this!!!\n");
return false;
}
#endif
return true; // cache hit
}
db_free_lock(db);
node = db->ht[db->hash(key, db->maxlen)%HASH_SIZE];
while (node) {
c = db->cmp(key, node->key, db->maxlen);
if (c == 0) {
if (!(node->deleted)) {
db->cache = node;
found = true;
}
break;
}
if (c < 0)
node = node->left;
else
node = node->right;
}
db_free_unlock(db);
return found;
}
/**
* Get the data of the entry identifid by the key.
* @param self Interface of the database
@ -2326,7 +2367,7 @@ DBReleaser db_custom_release(DBRelease which)
* @param type Type of database
* @param options Options of the database
* @param maxlen Maximum length of the string to be used as key in string
* databases
* databases. If 0, the maximum number of maxlen is used (64K).
* @return The interface of the database
* @public
* @see #DBMap_impl
@ -2351,6 +2392,7 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi
options = db_fix_options(type, options);
/* Interface of the database */
db->vtable.iterator = db_obj_iterator;
db->vtable.exists = db_obj_exists;
db->vtable.get = db_obj_get;
db->vtable.getall = db_obj_getall;
db->vtable.vgetall = db_obj_vgetall;
@ -2389,6 +2431,9 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi
db->maxlen = maxlen;
db->global_lock = 0;
if( db->maxlen == 0 && (type == DB_STRING || type == DB_ISTRING) )
db->maxlen = UINT16_MAX;
return &db->vtable;
}
@ -2493,7 +2538,7 @@ void db_final(void)
"dbit_next %10u, dbit_prev %10u,\n"
"dbit_exists %10u, dbit_remove %10u,\n"
"dbit_destroy %10u, db_iterator %10u,\n"
"db_get %10u,\n"
"db_exits %10u, db_get %10u,\n"
"db_getall %10u, db_vgetall %10u,\n"
"db_ensure %10u, db_vensure %10u,\n"
"db_put %10u, db_remove %10u,\n"
@ -2523,7 +2568,7 @@ void db_final(void)
stats.dbit_next, stats.dbit_prev,
stats.dbit_exists, stats.dbit_remove,
stats.dbit_destroy, stats.db_iterator,
stats.db_get,
stats.db_exists, stats.db_get,
stats.db_getall, stats.db_vgetall,
stats.db_ensure, stats.db_vensure,
stats.db_put, stats.db_remove,

View File

@ -205,8 +205,6 @@ typedef int (*DBMatcher)(DBKey key, void* data, va_list args);
/**
* Format of the comparators used internally by the database system.
* Compares key1 to key2.
* <code>maxlen</code> is the maximum number of character used in DB_STRING and
* DB_ISTRING databases. If 0, the maximum number of maxlen is used (64K).
* Returns 0 is equal, negative if lower and positive is higher.
* @param key1 Key being compared
* @param key2 Key we are comparing to
@ -221,8 +219,6 @@ typedef int (*DBComparator)(DBKey key1, DBKey key2, unsigned short maxlen);
/**
* Format of the hashers used internally by the database system.
* Creates the hash of the key.
* <code>maxlen</code> is the maximum number of character used in DB_STRING and
* DB_ISTRING databases. If 0, the maximum number of maxlen is used (64K).
* @param key Key being hashed
* @param maxlen Maximum number of characters used in DB_STRING and DB_ISTRING
* databases.
@ -359,6 +355,15 @@ struct DBMap {
*/
DBIterator* (*iterator)(DBMap* self);
/**
* Returns true if the entry exists.
* @param self Database
* @param key Key that identifies the entry
* @return true is the entry exists
* @protected
*/
bool (*exists)(DBMap* self, DBKey key);
/**
* Get the data of the entry identifid by the key.
* @param self Database
@ -580,6 +585,11 @@ struct DBMap {
# define str2key(k) ((DBKey)(const char *)(k))
#endif /* not DB_MANUAL_CAST_TO_UNION */
#define db_exists(db,k) ( (db)->exists((db),(k)) )
#define idb_exists(db,k) ( (db)->exists((db),i2key(k)) )
#define uidb_exists(db,k) ( (db)->exists((db),ui2key(k)) )
#define strdb_exists(db,k) ( (db)->exists((db),str2key(k)) )
#define db_get(db,k) ( (db)->get((db),(k)) )
#define idb_get(db,k) ( (db)->get((db),i2key(k)) )
#define uidb_get(db,k) ( (db)->get((db),ui2key(k)) )
@ -707,7 +717,7 @@ DBReleaser db_custom_release(DBRelease which);
* @param type Type of database
* @param options Options of the database
* @param maxlen Maximum length of the string to be used as key in string
* databases
* databases. If 0, the maximum number of maxlen is used (64K).
* @return The interface of the database
* @public
* @see #DBType

View File

@ -40,9 +40,7 @@
#ifndef _ERS_H_
#define _ERS_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
/*****************************************************************************\
* (1) All public parts of the Entry Reusage System. *

View File

@ -1,19 +1,18 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "grfio.h"
#include "../common/cbasetypes.h"
#include "../common/showmsg.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "grfio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <zlib.h>
//----------------------------
// file entry table struct
@ -221,6 +220,23 @@ unsigned long grfio_crc32 (const unsigned char* buf, unsigned int len)
return crc32(crc32(0L, Z_NULL, 0), buf, len);
}
///////////////////////////////////////////////////////////////////////////////
/// Grf data sub : zip decode
int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
{
return uncompress(dest, destLen, source, sourceLen);
}
///////////////////////////////////////////////////////////////////////////////
/// Grf data sub : zip encode
int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
{
return compress(dest, destLen, source, sourceLen);
}
/***********************************************************
*** File List Subroutines ***
***********************************************************/
@ -431,9 +447,9 @@ void* grfio_reads(char* fname, int* size)
if (entry->cycle >= 0)
decode_des_etc(buf, entry->srclen_aligned, entry->cycle == 0, entry->cycle);
len = entry->declen;
uncompress(buf2, &len, buf, entry->srclen);
decode_zip(buf2, &len, buf, entry->srclen);
if (len != (uLong)entry->declen) {
ShowError("uncompress size mismatch err: %d != %d\n", (int)len, entry->declen);
ShowError("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen);
aFree(buf);
aFree(buf2);
return NULL;
@ -580,7 +596,7 @@ static int grfio_entryread(char* grfname, int gentry)
grf_filelist = (unsigned char *)aMallocA(eSize); // Get a Extend Size
fread(rBuf,1,rSize,fp);
fclose(fp);
uncompress(grf_filelist, &eSize, rBuf, rSize); // Decode function
decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function
list_size = eSize;
aFree(rBuf);

View File

@ -4,8 +4,6 @@
#ifndef _GRFIO_H_
#define _GRFIO_H_
#include <zlib.h>
void grfio_init(char*); // GRFIO Initialize
void grfio_final(void); // GRFIO Finalize
void* grfio_reads(char*,int*); // GRFIO data file read & size get
@ -16,4 +14,7 @@ char *grfio_find_file(char *fname);
int grfio_size(char*); // GRFIO data file size get
unsigned long grfio_crc32(const unsigned char *buf, unsigned int len);
int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
#endif /* _GRFIO_H_ */

View File

@ -222,7 +222,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
if (((long) size) < 0) {
ShowError("_mmalloc: %d\n", size);
return 0;
return NULL;
}
if(size == 0) {
@ -380,7 +380,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func )
{
ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line);
} else {
head->size = -1;
head->size = 0xFFFF;
if(head_large->prev) {
head_large->prev->next = head_large->next;
} else {
@ -428,7 +428,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func )
hash_unfill[ block->unit_hash ] = block;
}
head->size = block->unit_unfill;
block->unit_unfill = (unsigned short)(((uintptr)head - (uintptr)block->data) / block->unit_size);
block->unit_unfill = (unsigned short)(((uintptr_t)head - (uintptr_t)block->data) / block->unit_size);
}
}
}
@ -636,7 +636,6 @@ static void memmgr_final (void)
fclose(log_fp);
}
#endif /* LOG_MEMMGR */
return;
}
static void memmgr_init (void)
@ -646,7 +645,6 @@ static void memmgr_init (void)
ShowStatus("Memory manager initialised: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile);
memset(hash_unfill, 0, sizeof(hash_unfill));
#endif /* LOG_MEMMGR */
return;
}
#endif /* USE_MEMMGR */
@ -679,7 +677,6 @@ void malloc_final (void)
#ifdef USE_MEMMGR
memmgr_final ();
#endif
return;
}
void malloc_init (void)
@ -687,5 +684,4 @@ void malloc_init (void)
#ifdef USE_MEMMGR
memmgr_init ();
#endif
return;
}

View File

@ -207,8 +207,19 @@ struct point {
short x,y;
};
enum e_skill_flag
{
SKILL_FLAG_PERMANENT,
SKILL_FLAG_TEMPORARY,
SKILL_FLAG_PLAGIARIZED,
SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0'
//...
};
struct s_skill {
unsigned short id,lv,flag;
unsigned short id;
unsigned short lv;
unsigned short flag; // see enum e_skill_flag
};
struct global_reg {
@ -508,12 +519,6 @@ struct guild_castle {
int temp_guardians_max;
};
// for Brandish Spear calculations
struct square {
int val1[5];
int val2[5];
};
struct fame_list {
int id;
int fame;

View File

@ -4,9 +4,7 @@
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
////// Plugin functions ///////////////

View File

@ -4,10 +4,7 @@
#ifndef _PLUGINS_H_
#define _PLUGINS_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include "../common/plugin.h"
////// Dynamic Link Library functions ///////////////

83
src/common/random.c Normal file
View File

@ -0,0 +1,83 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "../common/timer.h" // gettick
#include "random.h"
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(HAVE_GETPID) || defined(HAVE_GETTID)
#include <sys/types.h>
#include <unistd.h>
#endif
#include <time.h> // time
#include <mt19937ar.h> // init_genrand, genrand_int32, genrand_res53
/// Initializes the random number generator with an appropriate seed.
void rnd_init(void)
{
uint32 seed = gettick();
seed += (uint32)time(NULL);
#if defined(WIN32)
seed += GetCurrentProcessId();
seed += GetCurrentThreadId();
#else
#if defined(HAVE_GETPID)
seed += (uint32)getpid();
#endif // HAVE_GETPID
#if defined(HAVE_GETTID)
seed += (uint32)gettid();
#endif // HAVE_GETTID
#endif
init_genrand(seed);
}
/// Initializes the random number generator.
void rnd_seed(uint32 seed)
{
init_genrand(seed);
}
/// Generates a random number in the interval [0, UINT32_MAX]
uint32 rnd(void)
{
return (uint32)genrand_int32();
}
/// Generates a random number in the interval [0, dice_faces)
/// NOTE: interval is open ended, so dice_faces is excluded (unless it's 0)
uint32 rnd_roll(uint32 dice_faces)
{
return (uint32)(rnd_uniform()*dice_faces);
}
/// Generates a random number in the interval [min, max]
/// Returns min if range is invalid.
int32 rnd_value(int32 min, int32 max)
{
if( min >= max )
return min;
return min + (int32)(rnd_uniform()*(max-min+1));
}
/// Generates a random number in the interval [0.0, 1.0)
/// NOTE: interval is open ended, so 1.0 is excluded
double rnd_uniform(void)
{
return ((uint32)genrand_int32())*(1.0/4294967296.0);// divided by 2^32
}
/// Generates a random number in the interval [0.0, 1.0) with 53-bit resolution
/// NOTE: interval is open ended, so 1.0 is excluded
/// NOTE: 53 bits is the maximum precision of a double
double rnd_uniform53(void)
{
return genrand_res53();
}

18
src/common/random.h Normal file
View File

@ -0,0 +1,18 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#ifndef _RANDOM_H_
#define _RANDOM_H_
#include "../common/cbasetypes.h"
void rnd_init(void);
void rnd_seed(uint32);
uint32 rnd(void);// [0, UINT32_MAX]
uint32 rnd_roll(uint32 dice_faces);// [0, dice_faces)
int32 rnd_value(int32 min, int32 max);// [min, max]
double rnd_uniform(void);// [0.0, 1.0)
double rnd_uniform53(void);// [0.0, 1.0)
#endif /* _RANDOM_H_ */

View File

@ -938,7 +938,7 @@ static int connect_check_(uint32 ip)
/// Timer function.
/// Deletes old connection history records.
static int connect_check_clear(int tid, unsigned int tick, int id, intptr data)
static int connect_check_clear(int tid, unsigned int tick, int id, intptr_t data)
{
int i;
int clear = 0;
@ -1118,6 +1118,9 @@ void socket_final(void)
/// Closes a socket.
void do_close(int fd)
{
if( fd <= 0 ||fd >= FD_SETSIZE )
return;// invalid
flush_fifo(fd); // Try to send what's left (although it might not succeed since it's a nonblocking socket)
sFD_CLR(fd, &readfds);// this needs to be done before closing the socket
sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes

View File

@ -4,9 +4,7 @@
#ifndef _SOCKET_H_
#define _SOCKET_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN // otherwise winsock2.h includes full windows.h

View File

@ -182,7 +182,7 @@ int Sql_Ping(Sql* self)
/// Wrapper function for Sql_Ping.
///
/// @private
static int Sql_P_KeepaliveTimer(int tid, unsigned int tick, int id, intptr data)
static int Sql_P_KeepaliveTimer(int tid, unsigned int tick, int id, intptr_t data)
{
Sql* self = (Sql*)data;
ShowInfo("Pinging SQL server to keep connection alive...\n");
@ -212,7 +212,7 @@ static int Sql_P_Keepalive(Sql* self)
// establish keepalive
ping_interval = timeout - 30; // 30-second reserve
//add_timer_func_list(Sql_P_KeepaliveTimer, "Sql_P_KeepaliveTimer");
return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr)self, ping_interval*1000);
return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000);
}

View File

@ -4,9 +4,7 @@
#ifndef _COMMON_SQL_H_
#define _COMMON_SQL_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include <stdarg.h>// va_list

View File

@ -441,6 +441,163 @@ bool bin2hex(char* output, unsigned char* input, size_t count)
/////////////////////////////////////////////////////////////////////
/// Parses a single field in a delim-separated string.
/// The delimiter after the field is skipped.
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if already done, -1 on error.
int sv_parse_next(struct s_svstate* sv)
{
enum {
START_OF_FIELD,
PARSING_FIELD,
PARSING_C_ESCAPE,
END_OF_FIELD,
TERMINATE,
END
} state;
const char* str;
int len;
enum e_svopt opt;
char delim;
int i;
if( sv == NULL )
return -1;// error
str = sv->str;
len = sv->len;
opt = sv->opt;
delim = sv->delim;
// check opt
if( delim == '\n' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_LF)) )
{
ShowError("sv_parse_next: delimiter '\\n' is not compatible with options SV_TERMINATE_LF or SV_TERMINATE_CRLF.\n");
return -1;// error
}
if( delim == '\r' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_CR)) )
{
ShowError("sv_parse_next: delimiter '\\r' is not compatible with options SV_TERMINATE_CR or SV_TERMINATE_CRLF.\n");
return -1;// error
}
if( sv->done || str == NULL )
{
sv->done = true;
return 0;// nothing to parse
}
#define IS_END() ( i >= len )
#define IS_DELIM() ( str[i] == delim )
#define IS_TERMINATOR() ( \
((opt&SV_TERMINATE_LF) && str[i] == '\n') || \
((opt&SV_TERMINATE_CR) && str[i] == '\r') || \
((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n') )
#define IS_C_ESCAPE() ( (opt&SV_ESCAPE_C) && str[i] == '\\' )
#define SET_FIELD_START() sv->start = i
#define SET_FIELD_END() sv->end = i
i = sv->off;
state = START_OF_FIELD;
while( state != END )
{
switch( state )
{
case START_OF_FIELD:// record start of field and start parsing it
SET_FIELD_START();
state = PARSING_FIELD;
break;
case PARSING_FIELD:// skip field character
if( IS_END() || IS_DELIM() || IS_TERMINATOR() )
state = END_OF_FIELD;
else if( IS_C_ESCAPE() )
state = PARSING_C_ESCAPE;
else
++i;// normal character
break;
case PARSING_C_ESCAPE:// skip escape sequence (validates it too)
{
++i;// '\\'
if( IS_END() )
{
ShowError("sv_parse_next: empty escape sequence\n");
return -1;
}
if( str[i] == 'x' )
{// hex escape
++i;// 'x'
if( IS_END() || !ISXDIGIT(str[i]) )
{
ShowError("sv_parse_next: \\x with no following hex digits\n");
return -1;
}
do{
++i;// hex digit
}while( !IS_END() && ISXDIGIT(str[i]));
}
else if( str[i] == '0' || str[i] == '1' || str[i] == '2' )
{// octal escape
++i;// octal digit
if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
++i;// octal digit
if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
++i;// octal digit
}
else if( strchr(SV_ESCAPE_C_SUPPORTED, str[i]) )
{// supported escape character
++i;
}
else
{
ShowError("sv_parse_next: unknown escape sequence \\%c\n", str[i]);
return -1;
}
state = PARSING_FIELD;
break;
}
case END_OF_FIELD:// record end of field and stop
SET_FIELD_END();
state = END;
if( IS_END() )
;// nothing else
else if( IS_DELIM() )
++i;// delim
else if( IS_TERMINATOR() )
state = TERMINATE;
break;
case TERMINATE:
#if 0
// skip line terminator
if( (opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n' )
i += 2;// CRLF
else
++i;// CR or LF
#endif
sv->done = true;
state = END;
break;
}
}
if( IS_END() )
sv->done = true;
sv->off = i;
#undef IS_END
#undef IS_DELIM
#undef IS_TERMINATOR
#undef IS_C_ESCAPE
#undef SET_FIELD_START
#undef SET_FIELD_END
return 1;
}
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
@ -463,147 +620,32 @@ bool bin2hex(char* output, unsigned char* input, size_t count)
/// @return Number of fields found in the string or -1 if an error occured
int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt)
{
int i;
struct s_svstate sv;
int count;
enum {
START_OF_FIELD,
PARSING_FIELD,
PARSING_C_ESCAPE,
END_OF_FIELD,
TERMINATE,
END
} state;
// check pos/npos
// initialize
if( out_pos == NULL ) npos = 0;
for( i = 0; i < npos; ++i )
out_pos[i] = -1;
for( count = 0; count < npos; ++count )
out_pos[count] = -1;
sv.str = str;
sv.len = len;
sv.off = startoff;
sv.opt = opt;
sv.delim = delim;
sv.done = false;
// check opt
if( delim == '\n' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_LF)) )
{
ShowError("sv_parse: delimiter '\\n' is not compatible with options SV_TERMINATE_LF or SV_TERMINATE_CRLF.\n");
return -1;// error
}
if( delim == '\r' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_CR)) )
{
ShowError("sv_parse: delimiter '\\r' is not compatible with options SV_TERMINATE_CR or SV_TERMINATE_CRLF.\n");
return -1;// error
}
// check str
if( str == NULL )
return 0;// nothing to parse
#define IS_END() ( i >= len )
#define IS_DELIM() ( str[i] == delim )
#define IS_TERMINATOR() ( \
((opt&SV_TERMINATE_LF) && str[i] == '\n') || \
((opt&SV_TERMINATE_CR) && str[i] == '\r') || \
((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n') )
#define IS_C_ESCAPE() ( (opt&SV_ESCAPE_C) && str[i] == '\\' )
#define SET_FIELD_START() if( npos > count*2+2 ) out_pos[count*2+2] = i
#define SET_FIELD_END() if( npos > count*2+3 ) out_pos[count*2+3] = i; ++count
i = startoff;
// parse
count = 0;
state = START_OF_FIELD;
if( npos > 0 ) out_pos[0] = startoff;// start
while( state != END )
if( npos > 0 ) out_pos[0] = startoff;
while( !sv.done )
{
if( npos > 1 ) out_pos[1] = i;// end
switch( state )
{
case START_OF_FIELD:// record start of field and start parsing it
SET_FIELD_START();
state = PARSING_FIELD;
break;
case PARSING_FIELD:// skip field character
if( IS_END() || IS_DELIM() || IS_TERMINATOR() )
state = END_OF_FIELD;
else if( IS_C_ESCAPE() )
state = PARSING_C_ESCAPE;
else
++i;// normal character
break;
case PARSING_C_ESCAPE:// skip escape sequence (validates it too)
{
++i;// '\\'
if( IS_END() )
{
ShowError("sv_parse: empty escape sequence\n");
return -1;
}
if( str[i] == 'x' )
{// hex escape
++i;// 'x'
if( IS_END() || !ISXDIGIT(str[i]) )
{
ShowError("sv_parse: \\x with no following hex digits\n");
return -1;
}
do{
++i;// hex digit
}while( !IS_END() && ISXDIGIT(str[i]));
}
else if( str[i] == '0' || str[i] == '1' || str[i] == '2' )
{// octal escape
++i;// octal digit
if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
++i;// octal digit
if( !IS_END() && str[i] >= '0' && str[i] <= '7' )
++i;// octal digit
}
else if( strchr(SV_ESCAPE_C_SUPPORTED, str[i]) )
{// supported escape character
++i;
}
else
{
ShowError("sv_parse: unknown escape sequence \\%c\n", str[i]);
return -1;
}
state = PARSING_FIELD;
break;
}
case END_OF_FIELD:// record end of field and continue
SET_FIELD_END();
if( IS_END() )
state = END;
else if( IS_DELIM() )
{
++i;// delim
state = START_OF_FIELD;
}
else if( IS_TERMINATOR() )
state = TERMINATE;
else
state = START_OF_FIELD;
break;
case TERMINATE:
#if 0
// skip line terminator
if( (opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n' )
i += 2;// CRLF
else
++i;// CR or LF
#endif
state = END;
break;
}
++count;
if( sv_parse_next(&sv) <= 0 )
return -1;// error
if( npos > count*2 ) out_pos[count*2] = sv.start;
if( npos > count*2+1 ) out_pos[count*2+1] = sv.end;
}
#undef IS_END
#undef IS_DELIM
#undef IS_TERMINATOR
#undef IS_C_ESCAPE
#undef SET_FIELD_START
#undef SET_FIELD_END
if( npos > 1 ) out_pos[1] = sv.off;
return count;
}

View File

@ -4,9 +4,7 @@
#ifndef _STRLIB_H_
#define _STRLIB_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include <stdarg.h>
#define __USE_GNU // required to enable strnlen on some platforms
@ -78,6 +76,27 @@ typedef enum e_svopt
/// Other escape sequences supported by the C compiler.
#define SV_ESCAPE_C_SUPPORTED "abtnvfr\?\"'\\"
/// Parse state.
/// The field is [start,end[
struct s_svstate
{
const char* str; //< string to parse
int len; //< string length
int off; //< current offset in the string
int start; //< where the field starts
int end; //< where the field ends
enum e_svopt opt; //< parse options
char delim; //< field delimiter
bool done; //< if all the text has been parsed
};
/// Parses a single field in a delim-separated string.
/// The delimiter after the field is skipped.
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if done, -1 on error.
int sv_parse_next(struct s_svstate* sv);
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.

View File

@ -241,7 +241,7 @@ static int acquire_timer(void)
/// Starts a new timer that is deleted once it expires (single-use).
/// Returns the timer's id.
int add_timer(unsigned int tick, TimerFunc func, int id, intptr data)
int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data)
{
int tid;
@ -259,7 +259,7 @@ int add_timer(unsigned int tick, TimerFunc func, int id, intptr data)
/// Starts a new timer that automatically restarts itself (infinite loop until manually removed).
/// Returns the timer's id, or INVALID_TIMER if it fails.
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr data, int interval)
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval)
{
int tid;

View File

@ -4,9 +4,7 @@
#ifndef _TIMER_H_
#define _TIMER_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#define DIFF_TICK(a,b) ((int)((a)-(b)))
@ -19,7 +17,7 @@
// Struct declaration
typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr data);
typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data);
struct TimerData {
unsigned int tick;
@ -30,7 +28,7 @@ struct TimerData {
// general-purpose storage
int id;
intptr data;
intptr_t data;
};
// Function prototype declaration
@ -38,8 +36,8 @@ struct TimerData {
unsigned int gettick(void);
unsigned int gettick_nocache(void);
int add_timer(unsigned int tick, TimerFunc func, int id, intptr data);
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr data, int interval);
int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data);
int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval);
const struct TimerData* get_timer(int tid);
int delete_timer(int tid, TimerFunc func);

View File

@ -4,10 +4,7 @@
#ifndef _UTILS_H_
#define _UTILS_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include <stdio.h> // FILE*
// generate a hex dump of the first 'length' bytes of 'buffer'

12
src/login/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
#
# setup
#
set( LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
#
# targets
#
add_subdirectory( txt )
add_subdirectory( sql )

View File

@ -3,16 +3,20 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/malloc.o ../common/obj_all/showmsg.o ../common/obj_all/utils.o \
../common/obj_all/strlib.o ../common/obj_all/grfio.o ../common/obj_all/mapindex.o \
../common/obj_all/ers.o ../common/obj_all/md5calc.o
../common/obj_all/ers.o ../common/obj_all/md5calc.o ../common/obj_all/random.o
COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
../common/grfio.h ../common/mapindex.h \
../common/ers.h ../common/md5calc.h
../common/ers.h ../common/md5calc.h ../common/random.h
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_SQL_H = ../common/sql.h
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
LOGIN_OBJ = login.o
LOGIN_TXT_OBJ = $(LOGIN_OBJ:%=obj_txt/%) \
obj_txt/account_txt.o obj_txt/ipban_txt.o obj_txt/loginlog_txt.o
@ -22,10 +26,11 @@ LOGIN_H = login.h account.h ipban.h loginlog.h
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
LOGIN_SERVER_SQL_DEPENDS=obj_sql $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ)
LOGIN_SERVER_SQL_DEPENDS=obj_sql $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ)
else
LOGIN_SERVER_SQL_DEPENDS=needs_mysql
endif
LOGIN_SERVER_TXT_DEPENDS=obj_txt $(LOGIN_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ)
@SET_MAKE@
@ -63,19 +68,25 @@ obj_sql:
test -d obj_sql || mkdir obj_sql
#executables
login-server: $(LOGIN_TXT_OBJ) $(COMMON_OBJ)
@CC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_TXT_OBJ) $(COMMON_OBJ) @LIBS@
login-server: $(LOGIN_SERVER_TXT_DEPENDS)
@CC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@
login-server_sql: $(LOGIN_SERVER_SQL_DEPENDS)
@CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @MYSQL_LIBS@
@CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @MYSQL_LIBS@
# login object files
obj_txt/%.o: %.c $(LOGIN_H) $(COMMON_H)
@CC@ @CFLAGS@ -DWITH_TXT @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_txt/%.o: %.c $(LOGIN_H) $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DWITH_TXT @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H)
@CC@ @CFLAGS@ -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing common object files
# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common txt
../common/obj_sql/%.o:
@$(MAKE) -C ../common sql
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar

View File

@ -58,7 +58,7 @@ static bool account_db_txt_iter_next(AccountDBIterator* self, struct mmo_account
static bool mmo_auth_fromstr(struct mmo_account* acc, char* str, unsigned int version);
static bool mmo_auth_tostr(const struct mmo_account* acc, char* str);
static void mmo_auth_sync(AccountDB_TXT* self);
static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr data);
static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr_t data);
/// public constructor
AccountDB* account_db_txt(void)
@ -183,7 +183,7 @@ static bool account_db_txt_init(AccountDB* self)
// initialize data saving timer
add_timer_func_list(mmo_auth_sync_timer, "mmo_auth_sync_timer");
db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr)db, AUTH_SAVING_INTERVAL);
db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr_t)db, AUTH_SAVING_INTERVAL);
return true;
}
@ -634,7 +634,7 @@ static void mmo_auth_sync(AccountDB_TXT* db)
db->auths_before_save = AUTHS_BEFORE_SAVE;
}
static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr data)
static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr_t data)
{
AccountDB_TXT* db = (AccountDB_TXT*)data;

View File

@ -35,7 +35,7 @@ static Sql* sql_handle = NULL;
static int cleanup_timer_id = INVALID_TIMER;
static bool ipban_inited = false;
int ipban_cleanup(int tid, unsigned int tick, int id, intptr data);
int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data);
// initialize
@ -246,7 +246,7 @@ void ipban_log(uint32 ip)
}
// remove expired bans
int ipban_cleanup(int tid, unsigned int tick, int id, intptr data)
int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
if( !login_config.ipban )
return 0;// ipban disabled

View File

@ -101,7 +101,7 @@ struct online_login_data {
};
static DBMap* online_db; // int account_id -> struct online_login_data*
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr data);
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data);
static void* create_online_user(DBKey key, va_list args)
{
@ -138,7 +138,7 @@ void remove_online_user(int account_id)
idb_remove(online_db, account_id);
}
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr data)
static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id);
if( p != NULL && p->waiting_disconnect == tid && p->account_id == id )
@ -176,7 +176,7 @@ static int online_data_cleanup_sub(DBKey key, void *data, va_list ap)
return 0;
}
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr data)
static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
online_db->foreach(online_db, online_data_cleanup_sub);
return 0;
@ -190,7 +190,7 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
{
int i, c;
for( i = 0, c = 0; i < MAX_SERVERS; ++i )
for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i )
{
int fd = server[i].fd;
if( session_isValid(fd) && fd != sfd )
@ -206,10 +206,46 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
}
/// Initializes a server structure.
void chrif_server_init(int id)
{
memset(&server[id], 0, sizeof(server[id]));
server[id].fd = -1;
}
/// Destroys a server structure.
void chrif_server_destroy(int id)
{
if( server[id].fd != -1 )
{
do_close(server[id].fd);
server[id].fd = -1;
}
}
/// Resets all the data related to a server.
void chrif_server_reset(int id)
{
online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
chrif_server_destroy(id);
chrif_server_init(id);
}
/// Called when the connection to Char Server is disconnected.
void chrif_on_disconnect(int id)
{
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
chrif_server_reset(id);
}
//-----------------------------------------------------
// periodic ip address synchronization
//-----------------------------------------------------
static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr data)
static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr_t data)
{
uint8 buf[2];
ShowInfo("IP Sync in progress...\n");
@ -381,9 +417,10 @@ int parse_fromchar(int fd)
uint32 ipl;
char ip[16];
ARR_FIND( 0, MAX_SERVERS, id, server[id].fd == fd );
if( id == MAX_SERVERS )
ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
if( id == ARRAYLENGTH(server) )
{// not a char server
ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
set_eof(fd);
do_close(fd);
return 0;
@ -391,11 +428,9 @@ int parse_fromchar(int fd)
if( session[fd]->flag.eof )
{
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
memset(&server[id], 0, sizeof(struct mmo_char_server));
server[id].fd = -1;
do_close(fd);
server[id].fd = -1;
chrif_on_disconnect(id);
return 0;
}
@ -424,8 +459,9 @@ int parse_fromchar(int fd)
RFIFOSKIP(fd,23);
node = (struct auth_node*)idb_get(auth_db, account_id);
if( node != NULL &&
node->account_id == account_id &&
if( runflag == LOGINSERVER_ST_RUNNING &&
node != NULL &&
node->account_id == account_id &&
node->login_id1 == login_id1 &&
node->login_id2 == login_id2 &&
node->sex == sex_num2str(sex) /*&&
@ -1059,6 +1095,16 @@ void login_auth_ok(struct login_session_data* sd)
struct auth_node* node;
int i;
if( runflag != LOGINSERVER_ST_RUNNING )
{
// players can only login while running
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1;// server closed
WFIFOSET(fd,3);
return;
}
if( sd->level < login_config.min_level_to_connect )
{
ShowStatus("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d).\n", login_config.min_level_to_connect, sd->userid, sd->level);
@ -1070,8 +1116,8 @@ void login_auth_ok(struct login_session_data* sd)
}
server_num = 0;
for( i = 0; i < MAX_SERVERS; ++i )
if( session_isValid(server[i].fd) )
for( i = 0; i < ARRAYLENGTH(server); ++i )
if( session_isActive(server[i].fd) )
server_num++;
if( server_num == 0 )
@ -1133,7 +1179,7 @@ void login_auth_ok(struct login_session_data* sd)
memset(WFIFOP(fd,20), 0, 24);
WFIFOW(fd,44) = 0; // unknown
WFIFOB(fd,46) = sex_str2num(sd->sex);
for( i = 0, n = 0; i < MAX_SERVERS; ++i )
for( i = 0, n = 0; i < ARRAYLENGTH(server); ++i )
{
if( !session_isValid(server[i].fd) )
continue;
@ -1404,7 +1450,11 @@ int parse_login(int fd)
login_log(session[fd]->client_addr, sd->userid, 100, message);
result = mmo_auth(sd);
if( result == -1 && sd->sex == 'S' && sd->account_id < MAX_SERVERS && server[sd->account_id].fd == -1 )
if( runflag == LOGINSERVER_ST_RUNNING &&
result == -1 &&
sd->sex == 'S' &&
sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) &&
!session_isValid(server[sd->account_id].fd) )
{
ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
@ -1592,7 +1642,7 @@ static AccountDB* get_account_engine(void)
//--------------------------------------
void do_final(void)
{
int i, fd;
int i;
login_log(0, "login server", 100, "login server shutdown");
ShowStatus("Terminating...\n");
@ -1614,15 +1664,15 @@ void do_final(void)
accounts = NULL; // destroyed in account_engines
online_db->destroy(online_db, NULL);
auth_db->destroy(auth_db, NULL);
for( i = 0; i < ARRAYLENGTH(server); ++i )
chrif_server_destroy(i);
for (i = 0; i < MAX_SERVERS; i++) {
if ((fd = server[i].fd) >= 0) {
memset(&server[i], 0, sizeof(struct mmo_char_server));
server[i].fd = -1;
do_close(fd);
}
if( login_fd != -1 )
{
do_close(login_fd);
login_fd = -1;
}
do_close(login_fd);
ShowStatus("Finished.\n");
}
@ -1640,6 +1690,24 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_LOGIN;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
if( runflag != LOGINSERVER_ST_SHUTDOWN )
{
int id;
runflag = LOGINSERVER_ST_SHUTDOWN;
ShowStatus("Shutting down...\n");
// TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS]
for( id = 0; id < ARRAYLENGTH(server); ++id )
chrif_server_reset(id);
flush_fifos();
runflag = CORE_ST_STOP;
}
}
//------------------------------
// Login server initialization
//------------------------------
@ -1657,9 +1725,9 @@ int do_init(int argc, char** argv)
login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME);
srand((unsigned int)time(NULL));
for( i = 0; i < MAX_SERVERS; i++ )
server[i].fd = -1;
for( i = 0; i < ARRAYLENGTH(server); ++i )
chrif_server_init(i);
// initialize logging
if( login_config.log_login )
@ -1713,6 +1781,12 @@ int do_init(int argc, char** argv)
// server port open & binding
login_fd = make_listen_bind(login_config.login_ip, login_config.login_port);
if( runflag != CORE_ST_STOP )
{
shutdown_callback = do_shutdown;
runflag = LOGINSERVER_ST_RUNNING;
}
ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
login_log(0, "login server", 100, "login server started");

View File

@ -5,6 +5,14 @@
#define _LOGIN_H_
#include "../common/mmo.h" // NAME_LENGTH,SEX_*
#include "../common/core.h" // CORE_ST_LAST
enum E_LOGINSERVER_ST
{
LOGINSERVER_ST_RUNNING = CORE_ST_LAST,
LOGINSERVER_ST_SHUTDOWN,
LOGINSERVER_ST_LAST
};
#define LOGIN_CONF_NAME "conf/login_athena.conf"
#define LAN_CONF_NAME "conf/subnet_athena.conf"

View File

@ -0,0 +1,43 @@
#
# login sql
#
if( HAVE_common_sql )
message( STATUS "Creating target login-server_sql" )
set( SQL_LOGIN_HEADERS
"${LOGIN_SOURCE_DIR}/account.h"
"${LOGIN_SOURCE_DIR}/ipban.h"
"${LOGIN_SOURCE_DIR}/login.h"
"${LOGIN_SOURCE_DIR}/loginlog.h"
)
set( SQL_LOGIN_SOURCES
"${LOGIN_SOURCE_DIR}/account_sql.c"
"${LOGIN_SOURCE_DIR}/ipban_sql.c"
"${LOGIN_SOURCE_DIR}/login.c"
"${LOGIN_SOURCE_DIR}/loginlog_sql.c"
)
set( DEPENDENCIES common_sql )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_SQL )
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
source_group( login FILES ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} )
include_directories( ${INCLUDE_DIRS} )
add_executable( login-server_sql ${SOURCE_FILES} )
add_dependencies( login-server_sql ${DEPENDENCIES} )
target_link_libraries( login-server_sql ${LIBRARIES} ${DEPENDENCIES} )
set_target_properties( login-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
if( WITH_COMPONENT_RUNTIME )
cpack_add_component( Runtime_loginserver_sql DESCRIPTION "login-server (sql version)" DISPLAY_NAME "login-server_sql" GROUP Runtime )
install( TARGETS login-server_sql
DESTINATION "."
COMPONENT Runtime_loginserver_sql )
endif()
message( STATUS "Creating target login-server_sql - done" )
set( HAVE_login-server_sql ON CACHE BOOL "login-server_sql target is available" )
mark_as_advanced( HAVE_login-server_sql )
else()
message( STATUS "Skipping target login-server_sql (requires common_sql)" )
unset( HAVE_login-server_sql CACHE )
endif()

View File

@ -0,0 +1,43 @@
#
# login txt
#
if( HAVE_common_base )
message( STATUS "Creating target login-server" )
set( TXT_LOGIN_HEADERS
"${LOGIN_SOURCE_DIR}/account.h"
"${LOGIN_SOURCE_DIR}/ipban.h"
"${LOGIN_SOURCE_DIR}/login.h"
"${LOGIN_SOURCE_DIR}/loginlog.h"
)
set( TXT_LOGIN_SOURCES
"${LOGIN_SOURCE_DIR}/account_txt.c"
"${LOGIN_SOURCE_DIR}/ipban_txt.c"
"${LOGIN_SOURCE_DIR}/login.c"
"${LOGIN_SOURCE_DIR}/loginlog_txt.c"
)
set( DEPENDENCIES common_base )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_TXT )
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} )
source_group( login FILES ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} )
include_directories( ${INCLUDE_DIRS} )
add_executable( login-server ${SOURCE_FILES} )
add_dependencies( login-server ${DEPENDENCIES} )
target_link_libraries( login-server ${LIBRARIES} ${DEPENDENCIES} )
set_target_properties( login-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
if( WITH_COMPONENT_RUNTIME )
cpack_add_component( Runtime_loginserver_txt DESCRIPTION "login-server (txt version)" DISPLAY_NAME "login-server" GROUP Runtime )
install( TARGETS login-server
DESTINATION "."
COMPONENT Runtime_loginserver_txt )
endif()
message( STATUS "Creating target login-server - done" )
set( HAVE_login-server ON CACHE BOOL "login-server target is available" )
mark_as_advanced( HAVE_login-server )
else()
message( STATUS "Skipping target login-server (requires common_base)" )
unset( HAVE_login-server CACHE )
endif()

12
src/map/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
#
# setup
#
set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
#
# targets
#
add_subdirectory( txt )
add_subdirectory( sql )

View File

@ -3,16 +3,22 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/nullpo.o ../common/obj_all/malloc.o ../common/obj_all/showmsg.o \
../common/obj_all/utils.o ../common/obj_all/strlib.o ../common/obj_all/grfio.o \
../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/md5calc.o
../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/md5calc.o \
../common/obj_all/random.o
COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h \
../common/db.h ../common/plugins.h ../common/lock.h \
../common/nullpo.h ../common/malloc.h ../common/showmsg.h \
../common/utils.h ../common/strlib.h ../common/grfio.h \
../common/mapindex.h ../common/ers.h ../common/md5calc.h
../common/mapindex.h ../common/ers.h ../common/md5calc.h \
../common/random.h
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_SQL_H = ../common/sql.h
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \
npc_chat.o chat.o path.o itemdb.o mob.o script.o \
storage.o skill.o atcommand.o battle.o battleground.o \
@ -38,6 +44,7 @@ else
ALL_TARGET=txt
SQL_DEPENDS=needs_mysql
endif
TXT_DEPENDS=map-server
HAVE_PCRE=@HAVE_PCRE@
ifeq ($(HAVE_PCRE),yes)
@ -53,7 +60,7 @@ endif
all: $(ALL_DEPENDS)
txt: map-server
txt: $(TXT_DEPENDS)
sql: $(SQL_DEPENDS)
@ -87,21 +94,24 @@ obj_sql:
# executables
map-server: obj_txt $(MAP_TXT_OBJ) $(COMMON_OBJ)
@CC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_TXT_OBJ) $(COMMON_OBJ) @LIBS@ @PCRE_LIBS@
@CC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@ @PCRE_LIBS@
map-server_sql: obj_sql $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ)
@CC@ @LDFLAGS@ -o ../../map-server_sql@EXEEXT@ $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
@CC@ @LDFLAGS@ -o ../../map-server_sql@EXEEXT@ $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
# map object files
obj_txt/%.o: %.c $(MAP_H) $(COMMON_H)
@CC@ @CFLAGS@ $(PCRE_CFLAGS) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_txt/%.o: %.c $(MAP_H) $(COMMON_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) $(PCRE_CFLAGS) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(COMMON_SQL_H)
@CC@ @CFLAGS@ $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(COMMON_SQL_H) $(MT19937AR_H)
@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing common object files
# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common txt
../common/obj_sql/%.o:
@$(MAKE) -C ../common sql
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar

View File

@ -3988,23 +3988,9 @@ ACMD_FUNC(agitend2)
*------------------------------------------*/
ACMD_FUNC(mapexit)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
nullpo_retr(-1, sd);
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
if (sd->status.account_id != pl_sd->status.account_id)
clif_GM_kick(NULL, pl_sd);
mapit_free(iter);
clif_GM_kick(NULL, sd);
flush_fifos();
runflag = 0;
do_shutdown();
return 0;
}
@ -7098,9 +7084,9 @@ ACMD_FUNC(mobinfo)
if (mob->mvpitem[i].p > 0) {
j++;
if (j == 1)
sprintf(atcmd_output2, " %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100);
sprintf(atcmd_output2, " %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
else
sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100);
sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
strcat(atcmd_output, atcmd_output2);
}
}
@ -7117,7 +7103,7 @@ ACMD_FUNC(mobinfo)
* @showmobs by KarLaeda
* => For 5 sec displays the mobs on minimap
*------------------------------------------*/
int atshowmobs_timer(int tid, unsigned int tick, int id, intptr data)
int atshowmobs_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data* sd = map_id2sd(id);
if( sd == NULL )

View File

@ -154,7 +154,7 @@ struct delay_damage {
unsigned short attack_type;
};
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr data)
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct delay_damage *dat = (struct delay_damage *)data;
struct block_list *target = map_id2bl(dat->target);
@ -208,7 +208,7 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
if (src->type != BL_PC && amotion > 1000)
amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
add_timer(tick+amotion, battle_delay_damage_sub, src->id, (intptr)dat);
add_timer(tick+amotion, battle_delay_damage_sub, src->id, (intptr_t)dat);
return 0;
}
@ -1620,7 +1620,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case AS_SPLASHER:
skillratio += 400+50*skill_lv;
if(sd)
skillratio += 30 * pc_checkskill(sd,AS_POISONREACT);
skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
break;
case ASC_BREAKER:
skillratio += 100*skill_lv-100;

View File

@ -72,20 +72,19 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang
int battle_gettarget(struct block_list *bl);
int battle_getcurrentskill(struct block_list *bl);
//New definitions [Skotlex]
#define BCT_ENEMY 0x020000
//This should be (~BCT_ENEMY&BCT_ALL)
#define BCT_NOENEMY 0x1d0000
#define BCT_PARTY 0x040000
//This should be (~BCT_PARTY&BCT_ALL)
#define BCT_NOPARTY 0x1b0000
#define BCT_GUILD 0x080000
//This should be (~BCT_GUILD&BCT_ALL)
#define BCT_NOGUILD 0x170000
#define BCT_ALL 0x1f0000
#define BCT_NOONE 0x000000
#define BCT_SELF 0x010000
#define BCT_NEUTRAL 0x100000
enum e_battle_check_target
{//New definitions [Skotlex]
BCT_ENEMY = 0x020000,
BCT_NOENEMY = 0x1d0000, //This should be (~BCT_ENEMY&BCT_ALL)
BCT_PARTY = 0x040000,
BCT_NOPARTY = 0x1b0000, //This should be (~BCT_PARTY&BCT_ALL)
BCT_GUILD = 0x080000,
BCT_NOGUILD = 0x170000, //This should be (~BCT_GUILD&BCT_ALL)
BCT_ALL = 0x1f0000,
BCT_NOONE = 0x000000,
BCT_SELF = 0x010000,
BCT_NEUTRAL = 0x100000,
};
#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru]

View File

@ -236,7 +236,7 @@ int bg_send_xy_timer_sub(DBKey key, void *data, va_list ap)
return 0;
}
int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
return 0;

View File

@ -145,7 +145,7 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
if( i )
{// duplicate check. as the client does this too, only malicious intent should be caught here
ARR_FIND( 0, i, listidx, sd->buyingstore.items[i].nameid == nameid );
ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
if( listidx != i )
{// duplicate
ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);

View File

@ -31,6 +31,8 @@
#include <sys/types.h>
#include <time.h>
static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data);
static struct eri *auth_db_ers; //For reutilizing player login structures.
static DBMap* auth_db; // int id -> struct auth_node*
@ -94,7 +96,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b27: Incoming, chrif_authfail -> 'client authentication failed'
int chrif_connected = 0;
int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
int char_fd = -1;
int srvinfo;
static char char_ip_str[128];
static uint32 char_ip = 0;
@ -110,6 +112,28 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
//This define should spare writing the check in every function. [Skotlex]
#define chrif_check(a) { if(!chrif_isconnected()) return a; }
/// Resets all the data.
void chrif_reset(void)
{
// TODO kick everyone out and reset everything [FlavioJS]
exit(EXIT_FAILURE);
}
/// Checks the conditions for the server to stop.
/// Releases the cookie when all characters are saved.
/// If all the conditions are met, it stops the core loop.
void chrif_check_shutdown(void)
{
if( runflag != MAPSERVER_ST_SHUTDOWN )
return;
if( auth_db->size(auth_db) > 0 )
return;
runflag = CORE_ST_STOP;
}
struct auth_node* chrif_search(int account_id)
{
return (struct auth_node*)idb_get(auth_db, account_id);
@ -244,9 +268,8 @@ int chrif_save(struct map_session_data *sd, int flag)
{
nullpo_retr(-1, sd);
if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out.
pc_makesavestatus(sd);
pc_makesavestatus(sd);
if (flag && sd->state.active) //Store player data which is quitting.
{
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
@ -363,6 +386,7 @@ int chrif_removemap(int fd)
static void chrif_save_ack(int fd)
{
chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
chrif_check_shutdown();
}
// request to move a character between mapservers
@ -472,6 +496,25 @@ static int chrif_reconnect(DBKey key,void *data,va_list ap)
return 0;
}
/// Called when all the connection steps are completed.
void chrif_on_ready(void)
{
ShowStatus("Map Server is now online.\n");
chrif_state = 2;
chrif_check_shutdown();
//If there are players online, send them to the char-server. [Skotlex]
send_users_tochar();
//Auth db reconnect handling
auth_db->foreach(auth_db,chrif_reconnect);
//Re-save any storages that were modified in the disconnection time. [Skotlex]
do_reconnect_storage();
}
/*==========================================
*
*------------------------------------------*/
@ -483,18 +526,7 @@ int chrif_sendmapack(int fd)
}
memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
ShowStatus("Map sending complete. Map Server is now online.\n");
chrif_state = 2;
//If there are players online, send them to the char-server. [Skotlex]
send_users_tochar();
//Auth db reconnect handling
auth_db->foreach(auth_db,chrif_reconnect);
//Re-save any storages that were modified in the disconnection time. [Skotlex]
do_reconnect_storage();
chrif_on_ready();
return 0;
}
@ -592,7 +624,8 @@ void chrif_authok(int fd)
}
sd = node->sd;
if(node->char_dat == NULL &&
if( runflag == MAPSERVER_ST_RUNNING &&
node->char_dat == NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 )
@ -661,7 +694,7 @@ int auth_db_cleanup_sub(DBKey key,void *data,va_list ap)
return 0;
}
int auth_db_cleanup(int tid, unsigned int tick, int id, intptr data)
int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
if(!chrif_isconnected()) return 0;
auth_db->foreach(auth_db, auth_db_cleanup_sub);
@ -838,7 +871,7 @@ int chrif_changedsex(int fd)
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
// remove specifical skills of Bard classes
for(i = 315; i <= 322; i++) {
if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@ -846,7 +879,7 @@ int chrif_changedsex(int fd)
}
// remove specifical skills of Dancer classes
for(i = 323; i <= 330; i++) {
if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@ -1292,22 +1325,22 @@ int chrif_char_online(struct map_session_data *sd)
return 0;
}
int chrif_disconnect(int fd)
{
if(fd == char_fd) {
char_fd = 0;
ShowWarning("Map Server disconnected from Char Server.\n\n");
chrif_connected = 0;
other_mapserver_count=0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
map_eraseallipport();
//Attempt to reconnect in a second. [Skotlex]
add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
}
return 0;
/// Called when the connection to Char Server is disconnected.
void chrif_on_disconnect(void)
{
if( chrif_connected != 1 )
ShowWarning("Connection to Char Server lost.\n\n");
chrif_connected = 0;
other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
map_eraseallipport();
//Attempt to reconnect in a second. [Skotlex]
add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
}
void chrif_update_ip(int fd)
{
uint32 new_ip;
@ -1352,10 +1385,9 @@ int chrif_parse(int fd)
if (session[fd]->flag.eof)
{
if (chrif_connected == 1)
chrif_disconnect(fd);
do_close(fd);
char_fd = -1;
chrif_on_disconnect();
return 0;
}
@ -1393,7 +1425,7 @@ int chrif_parse(int fd)
case 0x2afb: chrif_sendmapack(fd); break;
case 0x2afd: chrif_authok(fd); break;
case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
@ -1423,7 +1455,7 @@ int chrif_parse(int fd)
return 0;
}
int ping_char_server(int tid, unsigned int tick, int id, intptr data)
int ping_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
chrif_keepalive(char_fd);
@ -1431,7 +1463,7 @@ int ping_char_server(int tid, unsigned int tick, int id, intptr data)
}
// unused
int send_usercount_tochar(int tid, unsigned int tick, int id, intptr data)
int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
@ -1476,7 +1508,7 @@ int send_users_tochar(void)
* timer関数
* char鯖との接続を確認し
*------------------------------------------*/
int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
static int displayed = 0;
if (char_fd <= 0 || session[char_fd] == NULL)
@ -1491,7 +1523,6 @@ int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
char_fd = make_connection(char_ip, char_port);
if (char_fd == -1)
{ //Attempt to connect later. [Skotlex]
char_fd = 0;
return 0;
}
@ -1532,8 +1563,11 @@ int auth_db_final(DBKey k,void *d,va_list ap)
*------------------------------------------*/
int do_final_chrif(void)
{
if (char_fd > 0)
if( char_fd != -1 )
{
do_close(char_fd);
char_fd = -1;
}
auth_db->destroy(auth_db, auth_db_final);
ers_destroy(auth_db_ers);

View File

@ -25,6 +25,7 @@ int chrif_setip(const char* ip);
void chrif_setport(uint16 port);
int chrif_isconnected(void);
void chrif_check_shutdown(void);
extern int chrif_connected;
extern int other_mapserver_count;
@ -55,7 +56,6 @@ int send_users_tochar(void);
int chrif_char_online(struct map_session_data *sd);
int chrif_changesex(struct map_session_data *sd);
int chrif_chardisconnect(struct map_session_data *sd);
int check_connect_char_server(int tid, unsigned int tick, int id, intptr data);
int chrif_divorce(int partner_id1, int partner_id2);
int do_final_chrif(void);

View File

@ -581,10 +581,10 @@ int clif_authfail_fd(int fd, int type)
return 0;
}
/*==========================================
*
*------------------------------------------*/
int clif_charselectok(int id)
/// Reply from char-server.
/// Tells the player if it can connect to the char-server to select a character.
/// ok=1 : client disconnects and tries to connect to the char-server
int clif_charselectok(int id, uint8 ok)
{
struct map_session_data* sd;
int fd;
@ -595,7 +595,7 @@ int clif_charselectok(int id)
fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xb3));
WFIFOW(fd,0) = 0xb3;
WFIFOB(fd,2) = 1;
WFIFOB(fd,2) = ok;
WFIFOSET(fd,packet_len(0xb3));
return 0;
@ -700,7 +700,7 @@ int clif_clearunit_area(struct block_list* bl, clr_type type)
return 0;
}
static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr data)
static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = (struct block_list *)data;
clif_clearunit_area(bl, CLR_OUTSIGHT);
@ -713,7 +713,7 @@ int clif_clearunit_delayed(struct block_list* bl, unsigned int tick)
struct block_list *tbl;
tbl = (struct block_list*)aMalloc(sizeof (struct block_list));
memcpy (tbl, bl, sizeof (struct block_list));
add_timer(tick, clif_clearunit_delayed_sub, 0, (intptr)tbl);
add_timer(tick, clif_clearunit_delayed_sub, 0, (intptr_t)tbl);
return 0;
}
@ -1376,6 +1376,12 @@ static void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_
clif_specialeffect(&md->bl,421,AREA);
}
break;
case BL_PET:
if( vd->head_bottom )
{// needed to display pet equip properly
clif_pet_equip_area((TBL_PET*)bl);
}
break;
}
return;
}
@ -1415,7 +1421,7 @@ void clif_move(struct unit_data *ud)
/*==========================================
* Delays the map_quit of a player after they are disconnected. [Skotlex]
*------------------------------------------*/
static int clif_delayquit(int tid, unsigned int tick, int id, intptr data)
static int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = NULL;
@ -4192,7 +4198,7 @@ int clif_skillinfoblock(struct map_session_data *sd)
WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv);
safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
if(sd->status.skill[i].flag == 0)
if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
else
WFIFOB(fd,len+36) = 0;
@ -4229,7 +4235,7 @@ int clif_addskill(struct map_session_data *sd, int id )
WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
safestrncpy((char*)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
if( sd->status.skill[id].flag == 0 )
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
else
WFIFOB(fd,38) = 0;
@ -4279,38 +4285,49 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
return 0;
}
/*==========================================
*
* pl:
* 0 = Yellow cast aura
* 1 = Water elemental cast aura
* 2 = Earth elemental cast aura
* 3 = Fire elemental cast aura
* 4 = Wind elemental cast aura
* 5 = Poison elemental cast aura
* 6 = White cast aura
* ? = like 0
*------------------------------------------*/
int clif_skillcasting(struct block_list* bl,
int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl, int casttime)
/// Notifies clients, that an object is about to use a skill (ZC_USESKILL_ACK/ZC_USESKILL_ACK2)
/// 013e <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L
/// 07fb <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L <is disposable>.B
/// property:
/// 0 = Yellow cast aura
/// 1 = Water elemental cast aura
/// 2 = Earth elemental cast aura
/// 3 = Fire elemental cast aura
/// 4 = Wind elemental cast aura
/// 5 = Poison elemental cast aura
/// 6 = Holy elemental cast aura
/// ? = like 0
/// is disposable:
/// 0 = yellow chat text "[src name] will use skill [skill name]."
/// 1 = no text
void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime)
{
#if PACKETVER < 20091124
const int cmd = 0x13e;
#else
const int cmd = 0x7fb;
#endif
unsigned char buf[32];
WBUFW(buf,0) = 0x13e;
WBUFW(buf,0) = cmd;
WBUFL(buf,2) = src_id;
WBUFL(buf,6) = dst_id;
WBUFW(buf,10) = dst_x;
WBUFW(buf,12) = dst_y;
WBUFW(buf,14) = skill_num;
WBUFL(buf,16) = pl<0?0:pl; //Avoid sending negatives as element [Skotlex]
WBUFL(buf,16) = property<0?0:property; //Avoid sending negatives as element [Skotlex]
WBUFL(buf,20) = casttime;
if (disguised(bl)) {
clif_send(buf,packet_len(0x13e), bl, AREA_WOS);
WBUFL(buf,2) = -src_id;
clif_send(buf,packet_len(0x13e), bl, SELF);
} else
clif_send(buf,packet_len(0x13e), bl, AREA);
#if PACKETVER >= 20091124
WBUFB(buf,24) = 1; // isDisposable
#endif
return 0;
if (disguised(bl)) {
clif_send(buf,packet_len(cmd), bl, AREA_WOS);
WBUFL(buf,2) = -src_id;
clif_send(buf,packet_len(cmd), bl, SELF);
} else
clif_send(buf,packet_len(cmd), bl, AREA);
}
/*==========================================
@ -5821,28 +5838,32 @@ void clif_partyinvitationstate(struct map_session_data* sd)
WFIFOSET(fd, packet_len(0x2c9));
}
/*==========================================
*
*------------------------------------------*/
int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
/// Party invitation request (ZC_REQ_JOIN_GROUP/ZC_PARTY_JOIN_REQ)
/// 00fe <party id>.L <party name>.24B
/// 02c6 <party id>.L <party name>.24B
void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
#if PACKETVER < 20070821
const int cmd = 0xfe;
#else
const int cmd = 0x2c6;
#endif
int fd;
struct party_data *p;
nullpo_ret(sd);
nullpo_ret(tsd);
nullpo_retv(sd);
nullpo_retv(tsd);
fd=tsd->fd;
if( (p=party_search(sd->status.party_id))==NULL )
return 0;
return;
WFIFOHEAD(fd,packet_len(0xfe));
WFIFOW(fd,0)=0xfe;
WFIFOL(fd,2)=sd->status.account_id; // FIXME: This is party_id
WFIFOHEAD(fd,packet_len(cmd));
WFIFOW(fd,0)=cmd;
WFIFOL(fd,2)=sd->status.party_id;
memcpy(WFIFOP(fd,6),p->party.name,NAME_LENGTH);
WFIFOSET(fd,packet_len(0xfe));
return 0;
WFIFOSET(fd,packet_len(cmd));
}
/*==========================================
@ -7643,6 +7664,8 @@ int clif_refresh(struct map_session_data *sd)
clif_weather_check(sd);
if( sd->chatID )
chat_leavechat(sd,0);
if( sd->state.vending )
clif_openvending(sd, sd->bl.id, sd->vending);
if( pc_issit(sd) )
clif_sitting(&sd->bl); // FIXME: just send to self, not area
if( pc_isdead(sd) ) //When you refresh, resend the death packet.
@ -7650,6 +7673,9 @@ int clif_refresh(struct map_session_data *sd)
else
clif_changed_dir(&sd->bl, SELF);
// unlike vending, resuming buyingstore crashes the client.
buyingstore_close(sd);
#ifndef TXT_ONLY
mail_clear(sd);
#endif
@ -8371,6 +8397,12 @@ void clif_parse_WantToConnection(int fd, TBL_PC* sd)
return;
}
if( runflag != MAPSERVER_ST_RUNNING )
{// not allowed
clif_authfail_fd(fd,1);// server closed
return;
}
//Check for double login.
bl = map_id2bl(account_id);
if(bl && bl->type != BL_PC) {
@ -10620,12 +10652,12 @@ void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
party_invite(sd, t_sd);
}
/*==========================================
* Party invitation reply
* S 00ff <account ID>.L <flag>.L
* S 02c7 <account ID>.L <flag>.B
* flag: 0-reject, 1-accept
*------------------------------------------*/
/// Party invitation reply (CZ_JOIN_GROUP/CZ_PARTY_JOIN_REQ_ACK)
/// 00ff <party id>.L <flag>.L
/// 02c7 <party id>.L <flag>.B
/// flag:
/// 0 = reject
/// 1 = accept
void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd)
{
party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
@ -11995,6 +12027,11 @@ void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd)
return;
}
if( sd->bl.id == f_sd->bl.id )
{// adding oneself as friend
return;
}
// @noask [LuzZza]
if(f_sd->state.noask) {
clif_noask_sub(sd, f_sd, 5);
@ -12037,6 +12074,11 @@ void clif_parse_FriendsListReply(int fd, struct map_session_data *sd)
char_id = RFIFOL(fd,6);
reply = RFIFOB(fd,10);
if( sd->bl.id == account_id )
{// adding oneself as friend
return;
}
f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
if (f_sd == NULL)
return;
@ -12305,10 +12347,8 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
sd->menuskill_val = sd->menuskill_id = 0;
}
/*==========================================
* Question about Star Glaldiator save map [Komurka]
*------------------------------------------*/
void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv)
/// Star Gladiator's Feeling map confirmation prompt (ZC_STARPLACE)
void clif_feel_req(int fd, struct map_session_data *sd, int skilllv)
{
WFIFOHEAD(fd,packet_len(0x253));
WFIFOW(fd,0)=0x253;
@ -13957,11 +13997,11 @@ int clif_instance(int instance_id, int type, int flag)
switch( type )
{
case 1:
// S 0x2cb <Instance name>.63B <Standby Position>.W
// S 0x2cb <Instance name>.61B <Standby Position>.W
// Required to start the instancing information window on Client
// This window re-appear each "refresh" of client automatically until type 4 is send to client.
WBUFW(buf,0) = 0x02CB;
memcpy(WBUFP(buf,2),instance[instance_id].name,61);
memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
WBUFW(buf,63) = flag;
clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
break;
@ -13989,14 +14029,16 @@ int clif_instance(int instance_id, int type, int flag)
}
clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
break;
case 5: // R 02CE <message ID>.L
case 5:
// S 0x2ce <Message ID>.L
// 0 = Notification (EnterLimitDate update?)
// 1 = The Memorial Dungeon expired; it has been destroyed
// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
// 3 = The Memorial Dungeon has been removed.
// 4 = Just remove the window, maybe party/guild leave
// 4 = Create failure (removes the instance window)
WBUFW(buf,0) = 0x02CE;
WBUFL(buf,2) = flag;
//WBUFL(buf,6) = EnterLimitDate;
clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
break;
}
@ -14911,7 +14953,7 @@ static int packetdb_readdb(void)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
//#0x02C0
0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0,
0, 0, 0, 0, 0, 30, 30, 0, 0, 3, 0, 65, 4, 71, 10, 0,
0, 0, 0, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 59, 60, 8,
10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -15018,7 +15060,7 @@ static int packetdb_readdb(void)
6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
#endif
0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 0, 0, 0, 26, 0,
0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
//#0x0800
#if PACKETVER < 20091229
-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20,

View File

@ -220,7 +220,7 @@ uint16 clif_getport(void);
int clif_authok(struct map_session_data *);
int clif_authfail_fd(int fd,int type);
int clif_charselectok(int);
int clif_charselectok(int id, uint8 ok);
int clif_dropflooritem(struct flooritem_data *);
int clif_clearflooritem(struct flooritem_data *,int);
@ -326,7 +326,7 @@ int clif_skillup(struct map_session_data *sd,int skill_num);
int clif_addskill(struct map_session_data *sd, int skill);
int clif_deleteskill(struct map_session_data *sd, int skill);
int clif_skillcasting(struct block_list* bl,int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl,int casttime);
void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime);
int clif_skillcastcancel(struct block_list* bl);
int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype);
int clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick);
@ -404,7 +404,7 @@ int clif_movetoattack(struct map_session_data *sd,struct block_list *bl);
int clif_party_created(struct map_session_data *sd,int result);
int clif_party_member_info(struct party_data *p, struct map_session_data *sd);
int clif_party_info(struct party_data *p, struct map_session_data *sd);
int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
void clif_party_inviteack(struct map_session_data* sd, const char* nick, int flag);
int clif_party_option(struct party_data *p,struct map_session_data *sd,int flag);
int clif_party_withdraw(struct party_data* p, struct map_session_data* sd, int account_id, const char* name, int flag);
@ -515,7 +515,7 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un
int clif_party_xy_remove(struct map_session_data *sd); //Fix for minimap [Kevin]
void clif_gospel_info(struct map_session_data *sd, int type);
void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv);
void clif_feel_req(int fd, struct map_session_data *sd, int skilllv);
void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result);
void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type);
void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type);

View File

@ -61,8 +61,8 @@ struct{
}need[6];
} guild_skill_tree[MAX_GUILDSKILL];
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr data);
static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr data);
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data);
static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
/*==========================================
* Retrieves and validates the sd pointer for this guild member [Skotlex]
@ -308,7 +308,7 @@ int guild_payexp_timer_sub(DBKey dataid, void *data, va_list ap)
return 0;
}
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr data)
int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data)
{
guild_expcache_db->clear(guild_expcache_db,guild_payexp_timer_sub);
return 0;
@ -336,7 +336,7 @@ int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap)
}
//Code from party_send_xy_timer [Skotlex]
static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
guild_db->foreach(guild_db,guild_send_xy_timer_sub,tick);
return 0;
@ -1840,7 +1840,7 @@ int guild_castlealldataload(int len,struct guild_castle *gc)
}
// update mapserver castle data with new info
memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr)&c->guild_id - (uintptr)c));
memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr_t)&c->guild_id - (uintptr_t)c));
if( c->guild_id )
{

View File

@ -45,7 +45,7 @@
struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS]; //[orn]
struct skill_tree_entry hskill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE];
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr data);
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data);
static unsigned int hexptbl[MAX_LEVEL];
@ -196,7 +196,7 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
i = skillnum - HM_SKILLBASE;
if(hd->homunculus.skillpts > 0 &&
hd->homunculus.hskill[i].id &&
hd->homunculus.hskill[i].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
hd->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->homunculus.class_)
)
{
@ -480,7 +480,7 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
return 0;
}
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr data)
static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct homun_data *hd;

View File

@ -28,6 +28,24 @@
int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
struct s_instance instance[MAX_INSTANCE];
/// Checks whether given instance id is valid or not.
static bool instance_is_valid(int instance_id)
{
if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
{// out of range
return false;
}
if( instance[instance_id].state == INSTANCE_FREE )
{// uninitialized/freed instance slot
return false;
}
return true;
}
/*--------------------------------------
* name : instance name
* Return value could be
@ -62,13 +80,13 @@ int instance_create(int party_id, const char *name)
instance[i].idle_timer = INVALID_TIMER;
instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
instance[i].progress_timer = INVALID_TIMER;
instance[i].progress_timeout = instance[i].progress_timeoutval = 0;
instance[i].progress_timeout = 0;
instance[i].users = 0;
instance[i].party_id = party_id;
instance[i].ivar = NULL;
instance[i].svar = NULL;
memcpy( instance[i].name, name, sizeof(instance[i].name) );
safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
memset( instance[i].map, 0x00, sizeof(instance[i].map) );
p->instance_id = i;
@ -88,7 +106,7 @@ int instance_add_map(const char *name, int instance_id, bool usebasename)
if( m < 0 )
return -1; // source map not found
if( instance[instance_id].state == INSTANCE_FREE )
if( !instance_is_valid(instance_id) )
{
ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
return -1;
@ -158,6 +176,12 @@ int instance_add_map(const char *name, int instance_id, bool usebasename)
int instance_map2imap(int m, int instance_id)
{
int i;
if( !instance_is_valid(instance_id) )
{
return -1;
}
for( i = 0; i < instance[instance_id].num_map; i++ )
{
if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
@ -173,7 +197,6 @@ int instance_map2imap(int m, int instance_id)
*--------------------------------------*/
int instance_mapid2imapid(int m, int instance_id)
{
int i, max;
if( map[m].flag.src4instance == 0 )
return m; // not instances found for this map
else if( map[m].instance_id )
@ -182,16 +205,10 @@ int instance_mapid2imapid(int m, int instance_id)
return -1;
}
if( instance_id <= 0 )
if( !instance_is_valid(instance_id) )
return -1;
max = instance[instance_id].num_map;
for( i = 0; i < max; i++ )
if( map[instance[instance_id].map[i]].instance_src_map == m )
return instance[instance_id].map[i];
return -1;
return instance_map2imap(m, instance_id);
}
/*--------------------------------------
@ -214,13 +231,13 @@ void instance_init(int instance_id)
{
int i;
if( !instance_id )
if( !instance_is_valid(instance_id) )
return; // nothing to do
for( i = 0; i < instance[instance_id].num_map; i++ )
map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
instance[instance_id].state = INSTANCE_BUSSY;
instance[instance_id].state = INSTANCE_BUSY;
ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
}
@ -294,7 +311,7 @@ void instance_destroy_freesvar(void *key, void *data, va_list args)
/*--------------------------------------
* Timer to destroy instance by process or idle
*--------------------------------------*/
int instance_destroy_timer(int tid, unsigned int tick, int id, intptr data)
int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
instance_destroy(id);
return 0;
@ -309,7 +326,7 @@ void instance_destroy(int instance_id)
struct party_data *p;
time_t now = time(NULL);
if( !instance_id || instance[instance_id].state == INSTANCE_FREE )
if( !instance_is_valid(instance_id) )
return; // nothing to do
if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
@ -361,7 +378,7 @@ void instance_check_idle(int instance_id)
bool idle = true;
time_t now = time(NULL);
if( !instance_id || instance[instance_id].idle_timeoutval == 0 )
if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
return;
if( instance[instance_id].users )
@ -389,7 +406,7 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
{
time_t now = time(0);
if( !instance_id )
if( !instance_is_valid(instance_id) )
return;
if( instance[instance_id].progress_timer != INVALID_TIMER )
@ -399,13 +416,11 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
if( progress_timeout )
{
instance[instance_id].progress_timeoutval = progress_timeout;
instance[instance_id].progress_timeout = now + progress_timeout;
instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
}
else
{
instance[instance_id].progress_timeoutval = 0;
instance[instance_id].progress_timeout = 0;
instance[instance_id].progress_timer = INVALID_TIMER;
}
@ -444,6 +459,14 @@ void instance_check_kick(struct map_session_data *sd)
}
}
void do_final_instance(void)
{
int i;
for( i = 1; i < MAX_INSTANCE; i++ )
instance_destroy(i);
}
void do_init_instance(void)
{
memset(instance, 0x00, sizeof(instance));

View File

@ -7,10 +7,12 @@
#define MAX_MAP_PER_INSTANCE 10
#define MAX_INSTANCE 500
typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSSY } instance_state;
#define INSTANCE_NAME_LENGTH (60+1)
typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
struct s_instance {
char name[61]; // Instance Name - required for clif functions.
char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
instance_state state;
short instance_id;
int party_id;
@ -22,7 +24,7 @@ struct s_instance {
struct linkdb_node *ivar, *svar; // Instance Variable for scripts
int progress_timer;
time_t progress_timeout, progress_timeoutval;
time_t progress_timeout;
int idle_timer;
time_t idle_timeout, idle_timeoutval;
@ -43,6 +45,7 @@ void instance_check_idle(int instance_id);
void instance_check_kick(struct map_session_data *sd);
void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
void do_init_instance();
void do_final_instance(void);
void do_init_instance(void);
#endif

View File

@ -240,7 +240,7 @@ int map_freeblock_unlock (void)
// この関数は、do_timer() のトップレベルから呼ばれるので、
// block_free_lock を直接いじっても支障無いはず。
int map_freeblock_timer(int tid, unsigned int tick, int id, intptr data)
int map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data)
{
if (block_free_lock > 0) {
ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", block_free_lock);
@ -1217,7 +1217,7 @@ int map_get_new_object_id(void)
* map_clearflooritem(id)
* map.h?#defineしてある
*------------------------------------------*/
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data)
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct flooritem_data* fitem = (struct flooritem_data*)idb_get(id_db, id);
if( fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid) )
@ -2146,7 +2146,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap)
return 1;
}
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data)
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
{
int count;
const int m = id;
@ -2727,7 +2727,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
}
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
uncompress(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
CREATE(m->cell, struct mapcell, size);
@ -3436,9 +3436,6 @@ void do_final(void)
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
map_quit(sd);
mapit_free(iter);
for( i = 0; i < MAX_INSTANCE; i++ )
instance_destroy(i);
id_db->foreach(id_db,cleanup_db_sub);
chrif_char_reset_offline();
@ -3449,6 +3446,7 @@ void do_final(void)
do_final_chrif();
do_final_npc();
do_final_script();
do_final_instance();
do_final_itemdb();
do_final_storage();
do_final_guild();
@ -3491,7 +3489,7 @@ void do_final(void)
#ifndef TXT_ONLY
map_sql_close();
#endif /* not TXT_ONLY */
ShowStatus("Successfully terminated.\n");
ShowStatus("Finished.\n");
}
static int map_abort_sub(struct map_session_data* sd, va_list ap)
@ -3573,6 +3571,27 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_MAP;
}
/// Called when a terminate signal is received.
void do_shutdown(void)
{
if( runflag != MAPSERVER_ST_SHUTDOWN )
{
runflag = MAPSERVER_ST_SHUTDOWN;
ShowStatus("Shutting down...\n");
{
struct map_session_data* sd;
struct s_mapiterator* iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
clif_GM_kick(NULL, sd);
mapit_free(iter);
flush_fifos();
}
chrif_check_shutdown();
}
}
int do_init(int argc, char *argv[])
{
int i;
@ -3710,6 +3729,12 @@ int do_init(int argc, char *argv[])
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port);
if( runflag != CORE_ST_STOP )
{
shutdown_callback = do_shutdown;
runflag = MAPSERVER_ST_RUNNING;
}
return 0;
}

View File

@ -4,9 +4,8 @@
#ifndef _MAP_H_
#define _MAP_H_
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include "../common/core.h" // CORE_ST_LAST
#include "../common/mmo.h"
#include "../common/mapindex.h"
#include "../common/db.h"
@ -16,6 +15,13 @@
struct npc_data;
struct item_data;
enum E_MAPSERVER_ST
{
MAPSERVER_ST_RUNNING = CORE_ST_LAST,
MAPSERVER_ST_SHUTDOWN,
MAPSERVER_ST_LAST
};
//Uncomment to enable the Cell Stack Limit mod.
//It's only config is the battle_config cell_stack_limit.
//Only chars affected are those defined in BL_CHAR (mobs and players currently)
@ -615,8 +621,8 @@ int map_quit(struct map_session_data *);
bool map_addnpc(int,struct npc_data *);
// <20>°ƒAƒCƒeƒ€ŠÖ˜A
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data);
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data);
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data);
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data);
#define map_clearflooritem(id) map_clearflooritem_timer(0,0,id,1)
int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int first_charid,int second_charid,int third_charid,int flags);
@ -739,4 +745,6 @@ extern char mob_db2_db[32];
#endif /* not TXT_ONLY */
void do_shutdown(void);
#endif /* _MAP_H_ */

View File

@ -184,7 +184,7 @@ static void script_save_mapreg(void)
mapreg_dirty = false;
}
static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr data)
static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data)
{
if( mapreg_dirty )
script_save_mapreg();

View File

@ -151,7 +151,7 @@ static void script_save_mapreg(void)
mapreg_dirty = false;
}
static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr data)
static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data)
{
if( mapreg_dirty )
script_save_mapreg();

View File

@ -215,7 +215,7 @@ int mercenary_save(struct mercenary_data *md)
return 1;
}
static int merc_contract_end(int tid, unsigned int tick, int id, intptr data)
static int merc_contract_end(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct mercenary_data *md;

View File

@ -81,7 +81,7 @@ const int mob_splendide[5] = { 1991, 1992, 1993, 1994, 1995 };
* Local prototype declaration (only required thing)
*------------------------------------------*/
static int mob_makedummymobdb(int);
static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr data);
static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data);
int mob_skillid2skillidx(int class_,int skillid);
/*==========================================
@ -507,7 +507,7 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i
/*==========================================
* Set a Guardian's guild data [Skotlex]
*------------------------------------------*/
static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr data)
static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data)
{ //Needed because the guild_data may not be available at guardian spawn time.
struct block_list* bl = map_id2bl(id);
struct mob_data* md;
@ -766,7 +766,7 @@ int mob_linksearch(struct block_list *bl,va_list ap)
/*==========================================
* mob spawn with delay (timer function)
*------------------------------------------*/
int mob_delayspawn(int tid, unsigned int tick, int id, intptr data)
int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* bl = map_id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@ -1636,7 +1636,7 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
/*==========================================
* Negligent processing for mob outside PC field of view (interval timer function)
*------------------------------------------*/
static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr data)
static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data)
{
map_foreachmob(mob_ai_sub_lazy,tick);
return 0;
@ -1645,7 +1645,7 @@ static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* Serious processing for mob in PC field of view (interval timer function)
*------------------------------------------*/
static int mob_ai_hard(int tid, unsigned int tick, int id, intptr data)
static int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
if (battle_config.mob_ai&0x20)
@ -1684,7 +1684,7 @@ static struct item_drop* mob_setlootitem(struct item* item)
/*==========================================
* item drop with delay (timer function)
*------------------------------------------*/
static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr data)
static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
@ -1744,7 +1744,7 @@ static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, str
dlist->item = ditem;
}
int mob_timer_delete(int tid, unsigned int tick, int id, intptr data)
int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* bl = map_id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@ -1791,7 +1791,7 @@ int mob_deleteslave(struct mob_data *md)
return 0;
}
// Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex]
int mob_respawn(int tid, unsigned int tick, int id, intptr data)
int mob_respawn(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = map_id2bl(id);
@ -2296,7 +2296,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
}
if (dlist->item) //There are drop items.
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr)dlist);
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
else //No drops
ers_free(item_drop_list_ers, dlist);
} else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
@ -2310,7 +2310,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
dlist->item = NULL;
for(i = 0; i < md->lootitem_count; i++)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr)dlist);
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
}
if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai)
@ -3407,7 +3407,7 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor
*------------------------------------------*/
static bool mob_parse_dbrow(char** str)
{
struct mob_db *db;
struct mob_db *db, entry;
struct status_data *status;
int class_, i, k;
double exp, maxhp;
@ -3416,29 +3416,28 @@ static bool mob_parse_dbrow(char** str)
class_ = atoi(str[0]);
if (class_ <= 1000 || class_ > MAX_MOB_DB) {
ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
return false;
}
if (pcdb_checkid(class_)) {
ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n", class_);
ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
return false;
}
if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
ShowWarning("Mob with ID: %d not loaded. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d)\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
ShowError("mob_parse_dbrow: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
return false;
}
if (mob_db_data[class_] == NULL)
mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db));
memset(&entry, 0, sizeof(entry));
db = mob_db_data[class_];
db = &entry;
status = &db->status;
db->vd.class_ = class_;
strncpy(db->sprite, str[1], NAME_LENGTH);
strncpy(db->jname, str[2], NAME_LENGTH);
strncpy(db->name, str[3], NAME_LENGTH);
safestrncpy(db->sprite, str[1], sizeof(db->sprite));
safestrncpy(db->jname, str[2], sizeof(db->jname));
safestrncpy(db->name, str[3], sizeof(db->name));
db->lv = atoi(str[4]);
db->lv = cap_value(db->lv, 1, USHRT_MAX);
status->max_hp = atoi(str[5]);
@ -3489,12 +3488,12 @@ static bool mob_parse_dbrow(char** str)
status->def_ele = i%10;
status->ele_lv = i/20;
if (status->def_ele >= ELE_MAX) {
ShowWarning("Mob with ID: %d has invalid element type %d (max element is %d)\n", class_, status->def_ele, ELE_MAX-1);
status->def_ele = ELE_NEUTRAL;
ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", status->def_ele, class_, ELE_MAX-1);
return false;
}
if (status->ele_lv < 1 || status->ele_lv > 4) {
ShowWarning("Mob with ID: %d has invalid element level %d (max is 4)\n", class_, status->ele_lv);
status->ele_lv = 1;
ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", status->ele_lv, class_);
return false;
}
status->mode = (int)strtol(str[25], NULL, 0);
@ -3512,7 +3511,8 @@ static bool mob_parse_dbrow(char** str)
status->dmotion = atoi(str[29]);
if(battle_config.monster_damage_delay_rate != 100)
status->dmotion = status->dmotion * battle_config.monster_damage_delay_rate / 100;
// Fill in remaining status data by using a dummy monster.
data.bl.type = BL_MOB;
data.level = db->lv;
memcpy(&data.status, status, sizeof(struct status_data));
@ -3632,7 +3632,12 @@ static bool mob_parse_dbrow(char** str)
id->mob[k].id = class_;
}
}
// Finally insert monster's data into the database.
if (mob_db_data[class_] == NULL)
mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
return true;
}

View File

@ -239,7 +239,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist);
int mob_unlocktarget(struct mob_data *md, unsigned int tick);
struct mob_data* mob_spawn_dataset(struct spawn_data *data);
int mob_spawn(struct mob_data *md);
int mob_delayspawn(int tid, unsigned int tick, int id, intptr data);
int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data);
int mob_setdelayspawn(struct mob_data *md);
int mob_parse_dataset(struct spawn_data *data);
void mob_log_damage(struct mob_data *md, struct block_list *src, int damage);
@ -256,7 +256,7 @@ void mob_clear_spawninfo();
int do_init_mob(void);
int do_final_mob(void);
int mob_timer_delete(int tid, unsigned int tick, int id, intptr data);
int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data);
int mob_deleteslave(struct mob_data *md);
int mob_random_class (int *value, size_t count);

View File

@ -356,7 +356,7 @@ bool npc_event_isspecial(const char* eventname)
/*==========================================
* ŽžŒvƒCƒxƒƒgŽÀ<EFBFBD>s
*------------------------------------------*/
int npc_event_do_clock(int tid, unsigned int tick, int id, intptr data)
int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
{
static struct tm ev_tm_b; // tracks previous execution time
time_t timer;
@ -455,7 +455,7 @@ struct timer_event_data {
/*==========================================
* triger 'OnTimerXXXX' events
*------------------------------------------*/
int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data)
{
int next;
int old_rid, old_timer;
@ -498,9 +498,9 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
ted->time += next;
if( sd )
sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
else
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
}
else
{
@ -570,13 +570,13 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
if( sd )
{
ted->rid = sd->bl.id; // Attach only the player if attachplayerrid was used.
sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr)ted);
sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
}
else
{
ted->rid = 0;
nd->u.scr.timertick = tick; // Set when timer is started
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr)ted);
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
}
return 0;
@ -1164,8 +1164,8 @@ static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* i
// save list of bought items
for( i = 0; i < n; i++ )
{
script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr)item_list[i*2+1], &key_nameid);
script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr)item_list[i*2], &key_amount);
script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr_t)item_list[i*2+1], &key_nameid);
script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr_t)item_list[i*2], &key_amount);
}
// invoke event
@ -1369,8 +1369,9 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
{
if( sd->status.skill[MC_DISCOUNT].flag != 0 )
skill = sd->status.skill[MC_DISCOUNT].flag - 2;
if( sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0 )
skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
if( skill > 0 )
{
z = z * (double)skill * (double)battle_config.shop_exp/10000.;
@ -1401,8 +1402,8 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
{
idx = item_list[i*2]-2;
script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr)sd->status.inventory[idx].nameid, &key_nameid);
script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr)item_list[i*2+1], &key_amount);
script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);
script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount);
}
// invoke event
@ -1505,8 +1506,9 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
{
if( sd->status.skill[MC_OVERCHARGE].flag != 0 )
skill = sd->status.skill[MC_OVERCHARGE].flag - 2;
if( sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0 )
skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
if( skill > 0 )
{
z = z * (double)skill * (double)battle_config.shop_exp/10000.;
@ -2734,13 +2736,13 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
// check monster ID if exists!
if( mobdb_checkid(class_) == 0 )
{
ShowError("npc_parse_mob: Unknown mob ID : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
ShowError("npc_parse_mob: Unknown mob ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
if( num < 1 || num > 1000 )
{
ShowError("npc_parse_mob: Invalid number of monsters (must be inside the range [1,1000]) : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] (file '%s', line '%d').\n", num, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
@ -2786,7 +2788,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
}
if(mob.delay1>0xfffffff || mob.delay2>0xfffffff) {
ShowError("npc_parse_mob: wrong monsters spawn delays : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
ShowError("npc_parse_mob: Invalid spawn delays %u %u (file '%s', line '%d').\n", mob.delay1, mob.delay2, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
@ -2801,7 +2803,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
//Verify dataset.
if( !mob_parse_dataset(&mob) )
{
ShowError("npc_parse_mob: Invalid dataset : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
ShowError("npc_parse_mob: Invalid dataset for monster ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}

View File

@ -77,7 +77,7 @@ struct npc_data {
#define MAX_NPC_CLASS 1000
//Checks if a given id is a valid npc id. [Skotlex]
//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
#define npcdb_checkid(id) ((id >= 46 && id <= 125) || id == 139 || (id >= 400 && id <= MAX_NPC_CLASS) || id == INVISIBLE_CLASS)
#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == 139 || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS )
#ifdef PCRE_SUPPORT
void npc_chat_finalize(struct npc_data* nd);

View File

@ -32,7 +32,7 @@ static DBMap* party_db; // int party_id -> struct party_data*
static DBMap* party_booking_db; // Party Booking [Spiria]
static unsigned long party_booking_nextid = 1;
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data);
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
/*==========================================
* Fills the given party_member structure according to the sd provided.
@ -369,11 +369,19 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
return 1;
}
void party_reply_invite(struct map_session_data *sd,int account_id,int flag)
void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
{
struct map_session_data *tsd= map_id2sd(account_id);
struct map_session_data* tsd;
struct party_member member;
if( sd->party_invite != party_id )
{// forged
sd->party_invite = 0;
sd->party_invite_account = 0;
return;
}
tsd = map_id2sd(sd->party_invite_account);
if( flag == 1 && !sd->party_creating && !sd->party_joining )
{// accepted and allowed
sd->party_joining = true;
@ -832,7 +840,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in
return 0;
}
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct party_data* p;

View File

@ -62,7 +62,7 @@ int party_member_added(int party_id,int account_id,int char_id,int flag);
int party_leave(struct map_session_data *sd);
int party_removemember(struct map_session_data *sd,int account_id,char *name);
int party_member_withdraw(int party_id,int account_id,int char_id);
void party_reply_invite(struct map_session_data *sd,int account_id,int flag);
void party_reply_invite(struct map_session_data *sd,int party_id,int flag);
int party_recv_noinfo(int party_id);
int party_recv_info(struct party *sp);
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);

View File

@ -85,7 +85,7 @@ int pc_isGM(struct map_session_data* sd)
return sd->gmlevel;
}
static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr data)
static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
@ -123,7 +123,7 @@ void pc_delinvincibletimer(struct map_session_data* sd)
}
}
static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data)
static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
int i;
@ -295,7 +295,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type)
/*==========================================
Rental System
*------------------------------------------*/
static int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr data)
static int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
if( sd == NULL )
@ -695,7 +695,7 @@ bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd
return false;
}
if( !(b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF) )
if( !( ( b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF ) || b_sd->status.class_ == JOB_SUPER_NOVICE ) )
return false;
return true;
@ -1061,9 +1061,9 @@ int pc_reg_received(struct map_session_data *sd)
if (sd->cloneskill_id > 0) {
sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id;
sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
if (i < sd->status.skill[sd->cloneskill_id].lv)
if (sd->status.skill[sd->cloneskill_id].lv > i)
sd->status.skill[sd->cloneskill_id].lv = i;
sd->status.skill[sd->cloneskill_id].flag = 13; //cloneskill flag
sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED;
}
}
@ -1124,11 +1124,11 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
) {
if(!sd->status.skill[i].flag)
if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
skill_point += skill;
else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) {
skill_point += (sd->status.skill[i].flag - 2);
}
else
if(sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0)
skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
}
}
}
@ -1157,16 +1157,16 @@ int pc_calc_skilltree(struct map_session_data *sd)
for( i = 0; i < MAX_SKILL; i++ )
{
if( sd->status.skill[i].flag != 13 ) //Don't touch plagiarized skills
if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) //Don't touch plagiarized skills
sd->status.skill[i].id = 0; //First clear skills.
}
for( i = 0; i < MAX_SKILL; i++ )
{
if( sd->status.skill[i].flag && sd->status.skill[i].flag != 13 )
if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
{ // Restore original level of skills after deleting earned skills.
sd->status.skill[i].lv = (sd->status.skill[i].flag == 1)?0:sd->status.skill[i].flag-2;
sd->status.skill[i].flag = 0;
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
}
if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU )
@ -1177,7 +1177,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
continue;
sd->status.skill[i].id = i;
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
sd->status.skill[i].flag = 1; // Tag it as a non-savable, non-uppable, bonus skill
sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
else
{ //Link bard skills to dancer.
@ -1185,7 +1185,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
continue;
sd->status.skill[i-8].id = i - 8;
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
sd->status.skill[i-8].flag = 1; // Tag it as a non-savable, non-uppable, bonus skill
sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
}
}
@ -1216,10 +1216,11 @@ int pc_calc_skilltree(struct map_session_data *sd)
for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
if((k=skill_tree[c][i].need[j].id))
{
if (!sd->status.skill[k].id || sd->status.skill[k].flag == 13)
if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
k = 0; //Not learned.
else if (sd->status.skill[k].flag) //Real lerned level
k = sd->status.skill[skill_tree[c][i].need[j].id].flag-2;
else
if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
else
k = pc_checkskill(sd,k);
if (k < skill_tree[c][i].need[j].lv)
@ -1249,7 +1250,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if(inf2&INF2_SPIRIT_SKILL)
{ //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
sd->status.skill[id].lv = 1; // need to manually specify a skill level
sd->status.skill[id].flag = 1; //So it is not saved, and tagged as a "bonus" skill.
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
}
flag = 1; // skill list has changed, perform another pass
}
@ -1273,10 +1274,12 @@ int pc_calc_skilltree(struct map_session_data *sd)
if( sd->status.skill[id].id == 0 )
{
sd->status.skill[id].id = id;
sd->status.skill[id].flag = 1; // So it is not saved, and tagged as a "bonus" skill.
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
}
else
sd->status.skill[id].flag = sd->status.skill[id].lv+2;
{
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Remember original level
}
sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);
}
@ -1314,10 +1317,11 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill)
{
if( (k = skill_tree[c][i].need[j].id) )
{
if( !sd->status.skill[k].id || sd->status.skill[k].flag == 13 )
if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED )
k = 0; //Not learned.
else if( sd->status.skill[k].flag ) //Real lerned level
k = sd->status.skill[skill_tree[c][i].need[j].id].flag - 2;
else
if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
else
k = pc_checkskill(sd,k);
if( k < skill_tree[c][i].need[j].lv )
@ -1352,13 +1356,15 @@ int pc_clean_skilltree(struct map_session_data *sd)
{
int i;
for (i = 0; i < MAX_SKILL; i++){
if (sd->status.skill[i].flag == 13 || sd->status.skill[i].flag == 1)
if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED)
{
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
} else if (sd->status.skill[i].flag){
sd->status.skill[i].lv = sd->status.skill[i].flag-2;
}
else
if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0){
sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = 0;
}
}
@ -1716,14 +1722,14 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
script_run_autobonus(autobonus->other_script,sd->bl.id,sd->equip_index[j]);
}
autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr)autobonus);
autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr_t)autobonus);
sd->state.autobonus |= autobonus->pos;
status_calc_pc(sd,0);
return 0;
}
int pc_endautobonus(int tid, unsigned int tick, int id, intptr data)
int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
struct s_autobonus *autobonus = (struct s_autobonus *)data;
@ -2321,8 +2327,8 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->right_weapon.hp_drain[RC_BOSS].value += val;
}
else if(sd->state.lr_flag == 1) {
sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
sd->right_weapon.hp_drain[RC_BOSS].value += val;
sd->left_weapon.hp_drain[RC_NONBOSS].value += val;
sd->left_weapon.hp_drain[RC_BOSS].value += val;
}
break;
case SP_SP_DRAIN_VALUE:
@ -3060,8 +3066,8 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
case 0: //Set skill data overwriting whatever was there before.
sd->status.skill[id].id = id;
sd->status.skill[id].lv = level;
sd->status.skill[id].flag = 0;
if( !level ) //Remove skill.
sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
if( level == 0 ) //Remove skill.
{
sd->status.skill[id].id = 0;
clif_deleteskill(sd,id);
@ -3075,21 +3081,21 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
if( sd->status.skill[id].id == id ){
if( sd->status.skill[id].lv >= level )
return 0;
if( !sd->status.skill[id].flag ) //Non-granted skill, store it's level.
sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
} else {
sd->status.skill[id].id = id;
sd->status.skill[id].flag = 1;
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
}
sd->status.skill[id].lv = level;
break;
case 2: //Add skill bonus on top of what you had.
if( sd->status.skill[id].id == id ){
if( !sd->status.skill[id].flag ) // Store previous level.
sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
} else {
sd->status.skill[id].id = id;
sd->status.skill[id].flag = 1; //Set that this is a bonus skill.
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
}
sd->status.skill[id].lv += level;
break;
@ -4789,7 +4795,8 @@ const char* job_name(int class_)
case JOB_WEDDING:
case JOB_SUPER_NOVICE:
case JOB_GUNSLINGER:
case JOB_NINJA:
case JOB_XMAS:
return msg_txt(570 - JOB_WEDDING+class_);
@ -4870,11 +4877,6 @@ const char* job_name(int class_)
return msg_txt(617);
case JOB_SOUL_LINKER:
return msg_txt(618);
case JOB_GUNSLINGER:
return msg_txt(619);
case JOB_NINJA:
return msg_txt(620);
case JOB_RUNE_KNIGHT:
case JOB_WARLOCK:
@ -4958,7 +4960,7 @@ const char* job_name(int class_)
}
}
int pc_follow_timer(int tid, unsigned int tick, int id, intptr data)
int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct block_list *tbl;
@ -5507,7 +5509,7 @@ int pc_skillup(struct map_session_data *sd,int skill_num)
if( sd->status.skill_point > 0 &&
sd->status.skill[skill_num].id &&
sd->status.skill[skill_num].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
sd->status.skill[skill_num].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
{
sd->status.skill[skill_num].lv++;
@ -5537,11 +5539,11 @@ int pc_allskillup(struct map_session_data *sd)
nullpo_ret(sd);
for(i=0;i<MAX_SKILL;i++){
if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){
sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2;
sd->status.skill[i].flag=0;
if (!sd->status.skill[i].lv)
sd->status.skill[i].id=0;
if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
if (sd->status.skill[i].lv == 0)
sd->status.skill[i].id = 0;
}
}
@ -5771,7 +5773,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE && (sd->class_&MAPID_UPPERMASK) != MAPID_BABY )
{ // Official server does not include Basic Skill to be resetted. [Jobbie]
sd->status.skill[i].lv = 9;
sd->status.skill[i].flag = 0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
continue;
}
@ -5784,13 +5786,14 @@ int pc_resetskill(struct map_session_data* sd, int flag)
}
continue;
}
if( !sd->status.skill[i].flag )
if( sd->status.skill[i].flag == SKILL_FLAG_PERMANENT )
skill_point += lv;
else if( sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13 )
skill_point += (sd->status.skill[i].flag - 2);
else
if( sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0 )
skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
if( !(flag&2) )
{
{// reset
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
}
@ -5896,7 +5899,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr data)
static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
if( sd != NULL )
@ -6602,6 +6605,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
}
if(sd->cloneskill_id) {
if( sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED ) {
sd->status.skill[sd->cloneskill_id].id = 0;
sd->status.skill[sd->cloneskill_id].lv = 0;
sd->status.skill[sd->cloneskill_id].flag = 0;
clif_deleteskill(sd,sd->cloneskill_id);
}
sd->cloneskill_id = 0;
pc_setglobalreg(sd, "CLONE_SKILL", 0);
pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
@ -7261,7 +7270,7 @@ int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *v
/*==========================================
* ??
*------------------------------------------*/
static int pc_eventtimer(int tid, unsigned int tick, int id, intptr data)
static int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
char *p = (char *)data;
@ -7295,7 +7304,7 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
if( i == MAX_EVENTTIMER )
return 0;
sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr)aStrdup(name));
sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr_t)aStrdup(name));
sd->eventcount++;
return 1;
@ -7761,7 +7770,7 @@ int pc_calc_pvprank(struct map_session_data *sd)
/*==========================================
* PVP順位計算(timer)
*------------------------------------------*/
int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr data)
int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=NULL;
@ -7960,7 +7969,7 @@ int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
/*==========================================
* ? (timer??)
*------------------------------------------*/
int pc_autosave(int tid, unsigned int tick, int id, intptr data)
int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
{
int interval;
struct s_mapiterator* iter;
@ -8014,7 +8023,7 @@ static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
* timer to do the day [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
int map_day_timer(int tid, unsigned int tick, int id, intptr data)
int map_day_timer(int tid, unsigned int tick, int id, intptr_t data)
{
char tmp_soutput[1024];
@ -8035,7 +8044,7 @@ int map_day_timer(int tid, unsigned int tick, int id, intptr data)
* timer to do the night [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
int map_night_timer(int tid, unsigned int tick, int id, intptr data)
int map_night_timer(int tid, unsigned int tick, int id, intptr_t data)
{
char tmp_soutput[1024];

View File

@ -582,8 +582,8 @@ int pc_calc_skilltree(struct map_session_data *sd);
int pc_calc_skilltree_normalize_job(struct map_session_data *sd);
int pc_clean_skilltree(struct map_session_data *sd);
#define pc_checkoverhp(sd) (sd->battle_status.hp == sd->battle_status.max_hp)
#define pc_checkoversp(sd) (sd->battle_status.sp == sd->battle_status.max_sp)
#define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp)
#define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp)
int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype);
int pc_setsavepoint(struct map_session_data*,short,int,int);
@ -621,7 +621,7 @@ int pc_updateweightstatus(struct map_session_data *sd);
int pc_addautobonus(struct s_autobonus *bonus,char max,const char *script,short rate,unsigned int dur,short atk_type,const char *o_script,unsigned short pos,bool onskill);
int pc_exeautobonus(struct map_session_data* sd,struct s_autobonus *bonus);
int pc_endautobonus(int tid, unsigned int tick, int id, intptr data);
int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data);
int pc_delautobonus(struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore);
int pc_bonus(struct map_session_data*,int,int);
@ -715,7 +715,7 @@ int pc_cleareventtimer(struct map_session_data *sd);
int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick);
int pc_calc_pvprank(struct map_session_data *sd);
int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr data);
int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data);
int pc_ismarried(struct map_session_data *sd);
int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd);
@ -779,8 +779,8 @@ enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT};
// timer for night.day
extern int day_timer_tid;
extern int night_timer_tid;
int map_day_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
int map_night_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
int map_day_timer(int tid, unsigned int tick, int id, intptr_t data); // by [yor]
int map_night_timer(int tid, unsigned int tick, int id, intptr_t data); // by [yor]
// Rental System
void pc_inventory_rentals(struct map_session_data *sd);

View File

@ -189,7 +189,7 @@ int pet_sc_check(struct map_session_data *sd, int type)
return 0;
}
static int pet_hungry(int tid, unsigned int tick, int id, intptr data)
static int pet_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct pet_data *pd;
@ -858,6 +858,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
if (pd->ud.walktimer != INVALID_TIMER)
return 0; //Wait until the pet finishes walking back to master.
pd->status.speed = pd->petDB->speed;
pd->ud.state.change_walk_target = pd->ud.state.speed_changed = 1;
}
if (pd->target_id) {
@ -934,7 +935,7 @@ static int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
return 0;
}
static int pet_ai_hard(int tid, unsigned int tick, int id, intptr data)
static int pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
map_foreachpc(pet_ai_sub_foreachclient,tick);
@ -968,7 +969,7 @@ static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
return 0;
}
static int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr data)
static int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
@ -1029,7 +1030,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
pd->ud.canact_tick = gettick()+10000; // 10*1000msÌŠÔ<C5A0>EíÈ¢
if (dlist->item)
add_timer(gettick()+540,pet_delay_item_drop,0,(intptr)dlist);
add_timer(gettick()+540,pet_delay_item_drop,0,(intptr_t)dlist);
else
ers_free(item_drop_list_ers, dlist);
return 1;
@ -1038,7 +1039,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
/*==========================================
* pet bonus giving skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr data)
int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
@ -1080,7 +1081,7 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* pet recovery skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data)
int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
@ -1108,7 +1109,7 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data)
return 0;
}
int pet_heal_timer(int tid, unsigned int tick, int id, intptr data)
int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct status_data *status;
@ -1146,7 +1147,7 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* pet support skills [Skotlex]
*------------------------------------------*/
int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr data)
int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;

Some files were not shown because too many files have changed in this diff Show More