Jump to content

Mind Rapist

Active Member
  • Posts

    548
  • Joined

  • Last visited

  • Days Won

    6
  • Feedback

    0%

Posts posted by Mind Rapist

  1. Well it's double trouble especially on development mode think about having to pass an SQL query AND have to build a proto for the packs.

    I solved the 1st error by modifying my table and setting `size` to a SET type instead of an ENUM. Now the second error remains and I believe it has something to do with the korean name but no other source has had this before and that makes me wonder. BTW I'm using Vanilla r71k source if you know about any changes regarding the issue.

    EDIT: Seems like mob_proto's encoding has something to do with that. By converting from EUC-KR to ANSI all names become ??? and ... so to get it over with does anyone have mob_proto txt files in ANSI encoding without the ???'s?

    EDIT 2: After a lot of effords I changed the encoding. Now gives me this:

    ChildLoop: AsyncSQL: query failed: Data truncated for column 'setRaceFlag' at row 1 (query: replace into mob_proto (`vnum`, `name`, `locale_name`, `type`, `rank`, `battle_type`, `level`, `size`, `ai_flag`, `setRaceFlag`, `setImmuneFlag`, `on_click`, `empire`, `drop_item`, `resurrection_vnum`, `folder`, `st`, `dx`, `ht`, `iq`, `damage_min`, `damage_max`, `max_hp`, `regen_cycle`, `regen_percent`, `exp`, `gold_min`, `gold_max`, `def`, `attack_speed`, `move_speed`, `aggressive_hp_pct`, `aggressive_sight`, `attack_range`, `polymorph_item`, `enchant_curse`, `enchant_slow`, `enchant_poison`, `enchant_stun`, `enchant_critical`, `enchant_penetrate`, `resist_sword`, `resist_twohand`, `resist_dagger`, `resist_bell`, `resist_fan`, `resist_bow`, `resist_fire`, `resist_elect`, `resist_magic`, `resist_wind`, `resist_poison`, `dam_multiply`, `summon`, `drain_sp`, `skill_vnum0`, `skill_level0`, `skill_vnum1`, `skill_level1`, `skill_vnum2`, `skill_level2`, `skill_vnum3`, `skill_level3`, `skill_vnum4

    I would do the same I did with `size` only this key is already a SET.

  2. I enabled txt protos in my serverfiles instead of traditional SQL tables. Item_proto is just fine. Mob_proto had to be reverse-engineered from the client packs. Serverfiles and client are both from the same production (Fliege).

    I'm getting this:

    ChildLoop: AsyncSQL: query failed: Data truncated for column 'size' at row 1 (query: replace into mob_proto (`vnum`, `name`, `locale_name`, `type`, `rank`, `battle_type`, `level`, `size`, `ai_flag`, `setRaceFlag`, `setImmuneFlag`, `on_click`, `empire`, `drop_item`, `resurrection_vnum`, `folder`, `st`, `dx`, `ht`, `iq`, `damage_min`, `damage_max`, `max_hp`, `regen_cycle`, `regen_percent`, `exp`, `gold_min`, `gold_max`, `def`, `attack_speed`, `move_speed`, `aggressive_hp_pct`, `aggressive_sight`, `attack_range`, `polymorph_item`, `enchant_curse`, `enchant_slow`, `enchant_poison`, `enchant_stun`, `enchant_critical`, `enchant_penetrate`, `resist_sword`, `resist_twohand`, `resist_dagger`, `resist_bell`, `resist_fan`, `resist_bow`, `resist_fire`, `resist_elect`, `resist_magic`, `resist_wind`, `resist_poison`, `dam_multiply`, `summon`, `drain_sp`, `skill_vnum0`, `skill_level0`, `skill_vnum1`, `skill_level1`, `skill_vnum2`, `skill_level2`, `skill_vnum3`, `skill_level3`, `skill_vnum4`, `ski

    (yes this is how the error line ends!)

    and a lot of these:

    ChildLoop: AsyncSQL: query failed: Incorrect string value: '\xBB\xE7\xB3\xAA\xBF\xEE...' for column 'name' at row 1 (query: replace into mob_proto (`vnum`, `name`, `locale_name`, `type`, `rank`, `battle_type`, `level`, `size`, `ai_flag`, `setRaceFlag`, `setImmuneFlag`, `on_click`, `empire`, `drop_item`, `resurrection_vnum`, `folder`, `st`, `dx`, `ht`, `iq`, `damage_min`, `damage_max`, `max_hp`, `regen_cycle`, `regen_percent`, `exp`, `gold_min`, `gold_max`, `def`, `attack_speed`, `move_speed`, `aggressive_hp_pct`, `aggressive_sight`, `attack_range`, `polymorph_item`, `enchant_curse`, `enchant_slow`, `enchant_poison`, `enchant_stun`, `enchant_critical`, `enchant_penetrate`, `resist_sword`, `resist_twohand`, `resist_dagger`, `resist_bell`, `resist_fan`, `resist_bow`, `resist_fire`, `resist_elect`, `resist_magic`, `resist_wind`, `resist_poison`, `dam_multiply`, `summon`, `drain_sp`, `skill_vnum0`, `skill_level0`, `skill_vnum1`, `skill_level1`, `skill_vnum2`, `skill_level2`, `skill_vnum

    Before you say anything about NULLS I tried it - same result. I compared my source with a working source and they match. That means the problem is most definately at the txt file itself. I checked for tabulation errors - didn't find any. I removed everything that wasn't in the database.

    So now I'm at a dead end asking for advice. What could it be???

  3. #BUMP

    Same here. Log.txt:

    1225 04:55:03316 :: ľË¸˛: ĆÄŔĎ ¸đµĺŔÔ´Ď´Ů.
    1225 04:55:03319 :: The eterpack doesn't exist [pack/patch1]
    1225 04:55:03327 :: The eterpack doesn't exist [pack/patch1_texcache]
    1225 04:55:03331 :: The eterpack doesn't exist [pack/season3_eu]
    1225 04:55:03335 :: The eterpack doesn't exist [pack/season3_eu_texcache]
    1225 04:55:03402 :: The eterpack doesn't exist [pack/pc_texcache]
    1225 04:55:03426 :: The eterpack doesn't exist [pack/pc2_texcache]
    1225 04:55:03458 :: The eterpack doesn't exist [pack/monster_texcache]
    1225 04:55:03480 :: The eterpack doesn't exist [pack/monster2_texcache]
    1225 04:55:03501 :: The eterpack doesn't exist [pack/effect_texcache]
    1225 04:55:03531 :: The eterpack doesn't exist [pack/zone_texcache]
    1225 04:55:03551 :: The eterpack doesn't exist [pack/zonedgn_texcache]
    1225 04:55:03569 :: The eterpack doesn't exist [pack/terrain_texcache]
    1225 04:55:03589 :: The eterpack doesn't exist [pack/npc_texcache]
    1225 04:55:03608 :: The eterpack doesn't exist [pack/npc2_texcache]
    1225 04:55:03627 :: The eterpack doesn't exist [pack/tree_texcache]
    1225 04:55:03645 :: The eterpack doesn't exist [pack/guild_texcache]
    1225 04:55:03672 :: The eterpack doesn't exist [pack/item_texcache]
    1225 04:55:03689 :: The eterpack doesn't exist [pack/textureset_texcache]
    1225 04:55:03711 :: The eterpack doesn't exist [pack/property_texcache]
    1225 04:55:03733 :: The eterpack doesn't exist [pack/icon_texcache]
    1225 04:55:03735 :: The eterpack doesn't exist [pack/season1]
    1225 04:55:03737 :: The eterpack doesn't exist [pack/season1_texcache]
    1225 04:55:03739 :: The eterpack doesn't exist [pack/season2]
    1225 04:55:03741 :: The eterpack doesn't exist [pack/season2_texcache]
    1225 04:55:03762 :: The eterpack doesn't exist [pack/indoor_texcache]
    1225 04:55:03802 :: The eterpack doesn't exist [pack/outdoor_texcache]
    1225 04:55:03839 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03841 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03843 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03846 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03849 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03852 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03855 :: The eterpack doesn't exist [pack/sound_texcache]
    1225 04:55:03879 :: The eterpack doesn't exist [pack/sound2_texcache]
    1225 04:55:03883 :: The eterpack doesn't exist [pack/sound2_texcache]
    1225 04:55:03901 :: The eterpack doesn't exist [pack/bgm_texcache]
    1225 04:55:03926 :: The eterpack doesn't exist [pack/ETC_texcache]
    1225 04:55:03929 :: The eterpack doesn't exist [pack/ETC_texcache]
    1225 04:55:03949 :: The eterpack doesn't exist [pack/locale_texcache]
    1225 04:55:03952 :: The eterpack doesn't exist [pack/locale_texcache]
    1225 04:55:03971 :: The eterpack doesn't exist [pack/uiscript_texcache]
    1225 04:55:03974 :: The eterpack doesn't exist [pack/ETC_texcache]
    1225 04:55:03994 :: The eterpack doesn't exist [pack/uiloading_texcache]
    1225 04:55:00009 :: 
    1225 04:55:00013 :: ## Network - OffLine Phase ##
    1225 04:55:00016 :: 

     

  4. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Spoiler

    145924Cs5f4z4h.jpg
    145924jEngTgFh.png
    145924RS6ToaOh.png

     

    I made this script because I got tired of all the binary warnings about saving the file to Unicode format. So I am now releasing it to the community.

    This is a Windows PowerShell script that converts all the files of the destination that have the postfix *.cpp and *.h to UTF-8 (without BOM) encoding.

     

    I made this script because I got tired of all the binary warnings about saving the file to Unicode format. So I am now releasing it to the community.

    This is a Windows PowerShell script that converts all the files of the destination that have the postfix *.cpp and *.h to UTF-8 (without BOM) encoding.

    By default, the file will look inside the directory "C:\Users\user\Documents\" but there is a -Dir parameter you can use (besides editing the file of course). Specify your working directory and wait a few seconds for the process to start. After that, there is really nothing else to do!

     

    EXTRA: There is one more parameter you can specify here. A boolean check by the name -Src (disabled by default). If you pass "1" in here the script will automatically check for file extensions *.c and *.hpp (the source files of the Extern folder).

    • Metin2 Dev 17
    • Smile Tear 1
    • Think 1
    • Confused 1
    • Good 5
    • Love 2
    • Love 13
  5. 18 hours ago, Sonitex said:

    Replace those Chinese characters with 'exp'.

    
    						if (name == "경험치" || name == "exp")
    						{
    							dwVnum = CSpecialItemGroup::EXP;
    						}

     

    Thanks it worked :)

    I'm getting this at DB now:

    QueryLocaleSet: cannot set locale latin1 by 'mysql_set_character_set', errno 2019 Can't initialize character set utf8 (path: compiled_in)

    QueryLocaleSet: cannot set locale latin1 by 'mysql_set_character_set', errno 2019 Can't initialize character set utf8 (path: compiled_in)

    NOTE: I use MariaDB 10.3

  6. 30 minutes ago, WeedHex said:

    Check the  TAB/SPACE  syntax 

    I did it's all correct. I also did some digging. Seems like there was a group at the end of the file without closing bracket (deleted). The line error dissapeared. The only error left is:

    ReadSpecialDropItemFile: ReadSpecialDropItemFile : there is no item 경험치 : node oberork

    The chinese characters mean Yang or EXP (sometimes it's the one, sometimes the other). This one is the EXP.

    Node oberork is:

    Group	Oberork
    {
    	Vnum	50070
    	1	3140	1	30	30
    	2	3141	1	16	30
    	3	1110	1	30	30
    	4	1111	1	16	30
    	5	2130	1	30	30
    	6	2131	1	16	30
    	7	7140	1	30	30
    	8	7141	1	16	30
    	9	5100	1	30	30
    	10	5101	1	16	30
    	11	160	1	30	30
    	12	161	1	16	30
    	13	240	1	30	30
    	14	241	1	16	30
    	15	11671	1	30	30
    	16	11672	1	5	30
    	17	11271	1	30	30
    	18	11272	1	5	30
    	19	11471	1	30	30
    	20	11472	1	5	30
    	21	11871	1	30	30
    	22	11872	1	5	30
    	23	16161	1	30	30
    	24	16162	1	16	30
    	25	16163	1	7	30
    	26	17161	1	30	30
    	27	17162	1	16	30
    	28	17163	1	7	30
    	29	14161	1	30	30
    	30	14162	1	16	30
    	31	14163	1	7	30
    	32	70012	1	25
    	33	70038	1	25
    	34	25040	1	30
    	35	70048	1	25
    	36	70037	1	30
    	37	70014	1	30
    	38	70043	1	25
    	39	70005	1	25
    	40	70006	1	25
    	41	돈꾸러미	50000	20
    	42	돈꾸러미	100000	70
    	43	돈꾸러미	200000	9
    	44	27112	10	30
    	45	경험치	100000	10
    }

    I also tried different encodings (UTF-8, EUC-KR, 1253) no difference.

  7. I managed to compile successfully but I cannot start due to an issue with special_item_group.txt (Fliege files). The problem is with the chinese characters about the EXP reward from chests.

    If what needs to be done to launch is a source modification I'm requesting some assistance to find the part that needs to be edited.

    If the files are the problem I'm looking for 40k files (clean as SHIT! please) with no bugs and nothing but:

    • Energy system
    • Dragon soul system
    • Belt system
    • Nemere/Razador/Spider Baroness/Devil's catacombs
    • Official mounts/pets (no GF 16.2 pet system - just the default ones)
    • Cape dragonhead maps

    I'm not looking for another source or a client just for the serverfiles (MySQL tables, channels and quests)

  8. I'm trying to launch files by Fliege with vanilla core (latest). When I'm launching, I'm getting the following error:

    LoadGroup: CTextFileLoader::LoadGroup : must have a value (filename: locale/germany/special_item_group.txt line: 781 key: 1)
    ReadSpecialDropItemFile: ReadSpecialDropItemFile : there is no item 경험치 : node oberork
    Boot: cannot load SpecialItemGroup: locale/germany/special_item_group.txt

    The point is that:

    • line 781 of special_item_group.txt is fine (tabs and values etc...)
    • 경험치 == EXP from the chest - what's wrong with that???

    Is there any part of the code I have to edit to make it compatible? (specify file please) Or is it something else?

  9. 4 hours ago, arves100 said:

    If it builded libjpeg.lib you don't have to worry, about that you can also add it to the Visual studio project under "Ignore default libraries" you put MSVCRT.lib and MSVCRTD.lib

    OMG! That was it finally after a week I compiled the client! Thanks for everything @arves100 man you've helped me more than you realise ❤️

  10. On 12/18/2018 at 6:01 PM, arves100 said:

    If you are compiling your client in /MT (type of C++ runtime), switch to /MD or build libjpeg-turbo with /MT flag (rather than /MD).

    Second fix faster to do but it's not really reccomanded, add this to UserInterface.cpp: #pragma comment(linker, "/NODEFAULTLIB: MSVCRT.lib") #pragma comment(linker, "/NODEFAULTLIB: MSVCRTD.lib").

     

    For anyone having this error, please rebuild libjpeg or libjpeg-turbo with the toolset you're using, this fix everything.

    Thanks for the insight, @arves100. What I did in the first place was following your tutorial:

    so the problem seems to be at libjpeg-9c. After seeing your response I edited the CFLAGS of makefile.vc and I added -MT at the end just to be sure about the runtime. The libs were generated even tho I had an error in the end saying "cannot open file 'rdjpgcom.exe'" I tried to fix it by downloading it and pasting it into the folder (didn't work) but anw the libs were created so I copied them into the Extern folder and started compiling.

    The result was the same as my image.

    I also tried the 2nd solution you mentioned. The result was:

    IRcd1CQ.jpg

    Conclusion: C++ Runtime might not be as big of a deal as we thought. I'm suspecting the rdjpgcom.exe error has something to do with it but I'm not sure...

  11. On 9/23/2018 at 2:55 AM, Minion said:

    fix Assertion failed: (!ms_singleton), function singleton, file ./../../common/singleton.h, line 13.

    
    Open service.h
    Add:
    #define CUNIQUEMANAGER_FIX
    
    Open main.cpp
    Find: 
    DSManager dsManager;
    
    Add after:
    #ifdef CUNIQUEMANAGER_FIX
            CUniqueManager  cUManager;
    #endif
    
    Open questmanager.cpp
    
    Find:
    pUniqueManager = new CUniqueManager();
    master = pUniqueManager->Create("__DEFAULT__");
    character = pUniqueManager->Create("__CHARACTER__");
    
    Replace:
    #ifdef CUNIQUEMANAGER_FIX
    		master = CUniqueManager::instance().Create("__DEFAULT__");
    		character = CUniqueManager::instance().Create("__CHARACTER__");
    #else
    		pUniqueManager = new CUniqueManager();
    		master = pUniqueManager->Create("__DEFAULT__");
    		character = pUniqueManager->Create("__CHARACTER__");
    #endif
    
    Open questmanager.h
      
    Find:
    	CUniqueManager* pUniqueManager;
    
    Replace:
    #ifndef CUNIQUEMANAGER_FIX
    	CUniqueManager* pUniqueManager;
    #endif

    P.S. NO TESTED!!!!

    P.S.2 Sorry for my bad english

    questlua_unique.cpp

    I got this:

    questlua_unique.cpp:660:11: error: no member named 'UniqueMoveToPos' in
          'CUnique'

    Can someone help me define this function or give me the full source?

  12. I have this error output at the end of my build:

    Linking...../game_r70140-BETA_release
    release/guild.o: In function `CGuild::GuildPointChange(unsigned char, int, bool)':
    guild.cpp:(.text+0x3939): undefined reference to `CGuild::CGuild(CGuild const&)'
    guild.cpp:(.text+0x39d6): undefined reference to `CGuild::CGuild(CGuild const&)'
    release/guild.o: In function `CGuild::SkillLevelUp(unsigned int)':
    guild.cpp:(.text+0x48fb): undefined reference to `CGuild::CGuild(CGuild const&)'
    guild.cpp:(.text+0x49be): undefined reference to `CGuild::CGuild(CGuild const&)'
    clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
    gmake: *** [Makefile:90: ../game_r70140-BETA_release] Error 1

    guild.cpp file:

    Spoiler
    
    #include <functional>
    #include "stdafx.h"
    #include "utils.h"
    #include "config.h"
    #include "char.h"
    #include "packet.h"
    #include "desc_client.h"
    #include "buffer_manager.h"
    #include "char_manager.h"
    #include "db.h"
    #include "guild.h"
    #include "guild_manager.h"
    #include "affect.h"
    #include "p2p.h"
    #include "questmanager.h"
    #include "building.h"
    #include "locale_service.h"
    #include "log.h"
    #include "questmanager.h"
    
    extern int gguild_max_level;
    
    	SGuildMember::SGuildMember(LPCHARACTER ch, BYTE grade, DWORD offer_exp)
    : pid(ch->GetPlayerID()), grade(grade), is_general(0), job(ch->GetJob()), level(ch->GetLevel()), offer_exp(offer_exp), name(ch->GetName())
    {}
    	SGuildMember::SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, BYTE level, DWORD offer_exp, char* name)
    : pid(pid), grade(grade), is_general(is_general), job(job), level(level), offer_exp(offer_exp), name(name)
    {}
    
    namespace 
    {
    	struct FGuildNameSender
    	{
    		FGuildNameSender(DWORD id, const char* guild_name) : id(id), name(guild_name)
    		{
    			p.header = HEADER_GC_GUILD;
    			p.subheader = GUILD_SUBHEADER_GC_GUILD_NAME;
    			p.size = sizeof(p) + sizeof(DWORD) + GUILD_NAME_MAX_LEN;
    		}
    
    		void operator() (LPCHARACTER ch)
    		{
    			LPDESC d = ch->GetDesc();
    
    			if (d)
    			{
    				d->BufferedPacket(&p, sizeof(p));
    				d->BufferedPacket(&id, sizeof(id));
    				d->Packet(name, GUILD_NAME_MAX_LEN);
    			}
    		}
    
    		DWORD id;
    		const char * name;
    		TPacketGCGuild p;
    	};
    }
    
    CGuild::CGuild(TGuildCreateParameter & cp)
    {
    	Initialize();
    
    	m_general_count = 0;
    
    	m_iMemberCountBonus = 0;
    
    	strlcpy(m_data.name, cp.name, sizeof(m_data.name));
    	m_data.master_pid = cp.master->GetPlayerID();
    	strlcpy(m_data.grade_array[0].grade_name, LC_TEXT("±ζµεΐε"), sizeof(m_data.grade_array[0].grade_name));
    	m_data.grade_array[0].auth_flag = GUILD_AUTH_ADD_MEMBER | GUILD_AUTH_REMOVE_MEMBER | GUILD_AUTH_NOTICE | GUILD_AUTH_USE_SKILL;
    
    	for (int i = 1; i < GUILD_GRADE_COUNT; ++i)
    	{
    		strlcpy(m_data.grade_array[i].grade_name, LC_TEXT("±ζµεΏψ"), sizeof(m_data.grade_array[i].grade_name));
    		m_data.grade_array[i].auth_flag = 0;
    	}
    
    	std::unique_ptr<SQLMsg> pmsg (DBManager::instance().DirectQuery(
    				"INSERT INTO guild%s(name, master, sp, level, exp, skill_point, skill) "
    				"VALUES('%s', %u, 1000, 1, 0, 0, '\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0')", 
    				get_table_postfix(), m_data.name, m_data.master_pid));
    
    	// TODO if error occur?
    	m_data.guild_id = pmsg->Get()->uiInsertID;
    
    	for (int i = 0; i < GUILD_GRADE_COUNT; ++i)
    	{
    		DBManager::instance().Query("INSERT INTO guild_grade%s VALUES(%u, %d, '%s', %d)", 
    				get_table_postfix(),
    				m_data.guild_id, 
    				i + 1, 
    				m_data.grade_array[i].grade_name, 
    				m_data.grade_array[i].auth_flag);
    	}
    
    	ComputeGuildPoints();
    	m_data.power	= m_data.max_power;
    	m_data.ladder_point	= 0;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_CREATE, 0, &m_data.guild_id, sizeof(DWORD));
    
    	TPacketGuildSkillUpdate guild_skill;
    	guild_skill.guild_id = m_data.guild_id;
    	guild_skill.amount = 0;
    	guild_skill.skill_point = 0;
    	memset(guild_skill.skill_levels, 0, GUILD_SKILL_COUNT);
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_SKILL_UPDATE, 0, &guild_skill, sizeof(guild_skill));
    
    	// TODO GUILD_NAME
    	CHARACTER_MANAGER::instance().for_each_pc(FGuildNameSender(GetID(), GetName()));
    	/*
    	   TPacketDGGuildMember p;
    	   memset(&p, 0, sizeof(p));
    	   p.dwPID = cp.master->GetPlayerID();
    	   p.bGrade = 15;
    	   AddMember(&p);
    	 */
    	RequestAddMember(cp.master, GUILD_LEADER_GRADE);
    }
    
    void CGuild::Initialize()
    {
    	memset(&m_data, 0, sizeof(m_data));
    	m_data.level = 1;
    
    	for (int i = 0; i < GUILD_SKILL_COUNT; ++i)
    		abSkillUsable[i] = true;
    
    	m_iMemberCountBonus = 0;
    }
    
    CGuild::~CGuild()
    {
    }
    
    void CGuild::RequestAddMember(LPCHARACTER ch, int grade)
    {
    	if (ch->GetGuild())
    		return;
    
    	TPacketGDGuildAddMember gd;
    
    	if (m_member.find(ch->GetPlayerID()) != m_member.end())
    	{
    		sys_err("Already a member in guild %s[%d]", ch->GetName(), ch->GetPlayerID());
    		return;
    	}
    
    	gd.dwPID = ch->GetPlayerID();
    	gd.dwGuild = GetID();
    	gd.bGrade = grade;
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_ADD_MEMBER, 0, &gd, sizeof(TPacketGDGuildAddMember));
    }
    
    void CGuild::AddMember(TPacketDGGuildMember * p)
    {
    	TGuildMemberContainer::iterator it;
    
    	if ((it = m_member.find(p->dwPID)) == m_member.end())
    		m_member.insert(std::make_pair(p->dwPID, TGuildMember(p->dwPID, p->bGrade, p->isGeneral, p->bJob, p->bLevel, p->dwOffer, p->szName)));
    	else
    	{
    		TGuildMember & r_gm = it->second;
    		r_gm.pid = p->dwPID;
    		r_gm.grade = p->bGrade;
    		r_gm.job = p->bJob;
    		r_gm.offer_exp = p->dwOffer;
    		r_gm.is_general = p->isGeneral;
    	}
    
    	CGuildManager::instance().Link(p->dwPID, this);
    
    	SendListOneToAll(p->dwPID);
    
    	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(p->dwPID);
    
    	sys_log(0, "GUILD: AddMember PID %u, grade %u, job %u, level %u, offer %u, name %s ptr %p",
    			p->dwPID, p->bGrade, p->bJob, p->bLevel, p->dwOffer, p->szName, get_pointer(ch));
    
    	if (ch)
    		LoginMember(ch);
    	else
    		P2PLoginMember(p->dwPID);
    }
    
    bool CGuild::RequestRemoveMember(DWORD pid)
    {
    	TGuildMemberContainer::iterator it;
    
    	if ((it = m_member.find(pid)) == m_member.end())
    		return false;
    
    	if (it->second.grade == GUILD_LEADER_GRADE)
    		return false;
    
    	TPacketGuild gd_guild;
    
    	gd_guild.dwGuild = GetID();
    	gd_guild.dwInfo = pid;
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_REMOVE_MEMBER, 0, &gd_guild, sizeof(TPacketGuild));
    	return true;
    }
    
    bool CGuild::RemoveMember(DWORD pid)
    {
    	sys_log(0, "Receive Guild P2P RemoveMember");
    	TGuildMemberContainer::iterator it;
    
    	if ((it = m_member.find(pid)) == m_member.end())
    		return false;
    
    	if (it->second.grade == GUILD_LEADER_GRADE)
    		return false;
    
    	if (it->second.is_general)
    		m_general_count--;
    
    	m_member.erase(it);
    	SendOnlineRemoveOnePacket(pid);
    
    	CGuildManager::instance().Unlink(pid);
    
    	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(pid);
    
    	if (ch)
    	{
    		//GuildRemoveAffect(ch);
    		m_memberOnline.erase(ch);
    		ch->SetGuild(NULL);
    	}
    
    	if ( LC_IsBrazil() == true )
    	{
    		DBManager::instance().Query("REPLACE INTO guild_invite_limit VALUES(%d, %d)", GetID(), get_global_time());
    	}
    
    	return true;
    }
    
    void CGuild::P2PLoginMember(DWORD pid)
    {
    	if (m_member.find(pid) == m_member.end())
    	{
    		sys_err("GUILD [%d] is not a memeber of guild.", pid);
    		return;
    	}
    
    	m_memberP2POnline.insert(pid);
    
    	// Login event occur + Send List
    	TGuildMemberOnlineContainer::iterator it;
    
    	for (it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    		SendLoginPacket(*it, pid);
    }
    
    void CGuild::LoginMember(LPCHARACTER ch)
    {
    	if (m_member.find(ch->GetPlayerID()) == m_member.end())
    	{
    		sys_err("GUILD %s[%d] is not a memeber of guild.", ch->GetName(), ch->GetPlayerID());
    		return;
    	}
    
    	ch->SetGuild(this);
    
    	// Login event occur + Send List
    	TGuildMemberOnlineContainer::iterator it;
    
    	for (it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    		SendLoginPacket(*it, ch);
    
    	m_memberOnline.insert(ch);
    
    	SendAllGradePacket(ch);
    	SendGuildInfoPacket(ch);
    	SendListPacket(ch);
    	SendSkillInfoPacket(ch);
    	SendEnemyGuild(ch);
    
    	//GuildUpdateAffect(ch);
    }
    
    void CGuild::P2PLogoutMember(DWORD pid)
    {
    	if (m_member.find(pid)==m_member.end())
    	{
    		sys_err("GUILD [%d] is not a memeber of guild.", pid);
    		return;
    	}
    
    	m_memberP2POnline.erase(pid);
    
    	// Logout event occur
    	TGuildMemberOnlineContainer::iterator it;
    	for (it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    	{
    		SendLogoutPacket(*it, pid);
    	}
    }
    
    void CGuild::LogoutMember(LPCHARACTER ch)
    {
    	if (m_member.find(ch->GetPlayerID())==m_member.end())
    	{
    		sys_err("GUILD %s[%d] is not a memeber of guild.", ch->GetName(), ch->GetPlayerID());
    		return;
    	}
    
    	//GuildRemoveAffect(ch);
    
    	//ch->SetGuild(NULL);
    	m_memberOnline.erase(ch);
    
    	// Logout event occur
    	TGuildMemberOnlineContainer::iterator it;
    	for (it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    	{
    		SendLogoutPacket(*it, ch);
    	}
    }
    
    void CGuild::SendOnlineRemoveOnePacket(DWORD pid)
    {
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+4;
    	pack.subheader = GUILD_SUBHEADER_GC_REMOVE;
    
    	TEMP_BUFFER buf;
    	buf.write(&pack,sizeof(pack));
    	buf.write(&pid, sizeof(pid));
    
    	TGuildMemberOnlineContainer::iterator it;
    
    	for (it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    
    		if (d)
    			d->Packet(buf.read_peek(), buf.size());
    	}
    }
    
    void CGuild::SendAllGradePacket(LPCHARACTER ch)
    {
    	LPDESC d = ch->GetDesc();
    	if (!d)
    		return;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+1+GUILD_GRADE_COUNT*(sizeof(TGuildGrade)+1);
    	pack.subheader = GUILD_SUBHEADER_GC_GRADE;
    
    	TEMP_BUFFER buf;
    
    	buf.write(&pack, sizeof(pack));
    	BYTE n = 15;
    	buf.write(&n, 1);
    
    	for (int i=0;i<GUILD_GRADE_COUNT;i++)
    	{
    		BYTE j = i+1;
    		buf.write(&j, 1);
    		buf.write(&m_data.grade_array[i], sizeof(TGuildGrade));
    	}
    
    	d->Packet(buf.read_peek(), buf.size());
    }
    
    void CGuild::SendListOneToAll(LPCHARACTER ch)
    {
    	SendListOneToAll(ch->GetPlayerID());
    }
    
    void CGuild::SendListOneToAll(DWORD pid)
    {
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(TPacketGCGuild);
    	pack.subheader = GUILD_SUBHEADER_GC_LIST;
    
    	pack.size += sizeof(TGuildMemberPacketData);
    
    	char c[CHARACTER_NAME_MAX_LEN+1];
    	memset(c, 0, sizeof(c));
    
    	TGuildMemberContainer::iterator cit = m_member.find(pid);
    	if (cit == m_member.end())
    		return;
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!= m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    		if (!d) 
    			continue;
    
    		TEMP_BUFFER buf;
    
    		buf.write(&pack, sizeof(pack));
    
    		cit->second._dummy = 1;
    
    		buf.write(&(cit->second), sizeof(DWORD) * 3 +1);
    		buf.write(cit->second.name.c_str(), cit->second.name.length());
    		buf.write(c, CHARACTER_NAME_MAX_LEN + 1 - cit->second.name.length());
    		d->Packet(buf.read_peek(), buf.size());
    	}
    }
    
    void CGuild::SendListPacket(LPCHARACTER ch)
    {
    	/*
    	   List Packet
    
    	   Header
    	   Count (byte)
    	   [
    	   ...
    	   name_flag 1 - ΐΜΈ§ΐ» ΊΈ³»΄ΐ³Δ ΎΘΊΈ³»΄ΐ³Δ
    	   name CHARACTER_NAME_MAX_LEN+1
    	   ] * Count
    
    	 */
    	LPDESC d;
    	if (!(d=ch->GetDesc()))
    		return;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(TPacketGCGuild);
    	pack.subheader = GUILD_SUBHEADER_GC_LIST;
    
    	pack.size += sizeof(TGuildMemberPacketData) * m_member.size();
    
    	TEMP_BUFFER buf;
    
    	buf.write(&pack,sizeof(pack));
    
    	char c[CHARACTER_NAME_MAX_LEN+1];
    
    	for (TGuildMemberContainer::iterator it = m_member.begin(); it != m_member.end(); ++it)
    	{
    		it->second._dummy = 1;
    
    		buf.write(&(it->second), sizeof(DWORD)*3+1);
    
    		strlcpy(c, it->second.name.c_str(), MIN(sizeof(c), it->second.name.length() + 1));
    
    		buf.write(c, CHARACTER_NAME_MAX_LEN+1 );
    
    		if ( test_server )
    			sys_log(0 ,"name %s job %d  ", it->second.name.c_str(), it->second.job );
    	}
    
    	d->Packet(buf.read_peek(), buf.size());
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		SendLoginPacket(ch, *it);
    	}
    
    	for (TGuildMemberP2POnlineContainer::iterator it = m_memberP2POnline.begin(); it != m_memberP2POnline.end(); ++it)
    	{
    		SendLoginPacket(ch, *it);
    	}
    
    }
    
    void CGuild::SendLoginPacket(LPCHARACTER ch, LPCHARACTER chLogin)
    {
    	SendLoginPacket(ch, chLogin->GetPlayerID());
    }
    
    void CGuild::SendLoginPacket(LPCHARACTER ch, DWORD pid)
    {
    	/*
    	   Login Packet
    	   header 4
    	   pid 4
    	 */
    	if (!ch->GetDesc())
    		return;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+4;
    	pack.subheader = GUILD_SUBHEADER_GC_LOGIN;
    
    	TEMP_BUFFER buf;
    
    	buf.write(&pack, sizeof(pack));
    
    	buf.write(&pid, 4);
    
    	ch->GetDesc()->Packet(buf.read_peek(), buf.size());
    }
    
    void CGuild::SendLogoutPacket(LPCHARACTER ch, LPCHARACTER chLogout)
    {
    	SendLogoutPacket(ch, chLogout->GetPlayerID());
    }
    
    void CGuild::SendLogoutPacket(LPCHARACTER ch, DWORD pid)
    {
    	/*
    	   Logout Packet
    	   header 4
    	   pid 4
    	 */
    	if (!ch->GetDesc())
    		return;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+4;
    	pack.subheader = GUILD_SUBHEADER_GC_LOGOUT;
    
    	TEMP_BUFFER buf;
    
    	buf.write(&pack, sizeof(pack));
    	buf.write(&pid, 4);
    
    	ch->GetDesc()->Packet(buf.read_peek(), buf.size());
    }
    
    void CGuild::LoadGuildMemberData(SQLMsg* pmsg)
    {
    	if (pmsg->Get()->uiNumRows == 0)
    		return;
    
    	m_general_count = 0;
    
    	m_member.clear();
    
    	for (uint i = 0; i < pmsg->Get()->uiNumRows; ++i)
    	{
    		MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
    
    		DWORD pid = strtoul(row[0], (char**) NULL, 10);
    		BYTE grade = (BYTE) strtoul(row[1], (char**) NULL, 10);
    		BYTE is_general = 0;
    
    		if (row[2] && *row[2] == '1')
    			is_general = 1;
    
    		DWORD offer = strtoul(row[3], (char**) NULL, 10);
    		BYTE level = (BYTE)strtoul(row[4], (char**) NULL, 10);
    		BYTE job = (BYTE)strtoul(row[5], (char**) NULL, 10);
    		char * name = row[6];
    
    		if (is_general)
    			m_general_count++;
    
    		m_member.insert(std::make_pair(pid, TGuildMember(pid, grade, is_general, job, level, offer, name)));
    		CGuildManager::instance().Link(pid, this);
    	}
    }
    
    void CGuild::LoadGuildGradeData(SQLMsg* pmsg)
    {
    	/*
        // 15°³ ΎΖ΄ °΅΄ΙΌΊ ΑΈΐη
    	if (pmsg->Get()->iNumRows != 15)
    	{
    		sys_err("Query failed: getting guild grade data. GuildID(%d)", GetID());
    		return;
    	}
    	*/
    	for (uint i = 0; i < pmsg->Get()->uiNumRows; ++i)
    	{
    		MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
    		BYTE grade = 0;
    		str_to_number(grade, row[0]);
    		char * name = row[1];
    		DWORD auth = strtoul(row[2], NULL, 10);
    
    		if (grade >= 1 && grade <= 15)
    		{
    			//sys_log(0, "GuildGradeLoad %s", name);
    			strlcpy(m_data.grade_array[grade-1].grade_name, name, sizeof(m_data.grade_array[grade-1].grade_name));
    			m_data.grade_array[grade-1].auth_flag = auth;
    		}
    	}
    }
    void CGuild::LoadGuildData(SQLMsg* pmsg)
    {
    	if (pmsg->Get()->uiNumRows == 0)
    	{
    		sys_err("Query failed: getting guild data %s", pmsg->stQuery.c_str());
    		return;
    	}
    
    	MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
    	m_data.master_pid = strtoul(row[0], (char **)NULL, 10);
    	m_data.level = (BYTE)strtoul(row[1], (char **)NULL, 10);
    	m_data.exp = strtoul(row[2], (char **)NULL, 10);
    	strlcpy(m_data.name, row[3], sizeof(m_data.name));
    
    	m_data.skill_point = (BYTE) strtoul(row[4], (char **) NULL, 10);
    	if (row[5])
    		thecore_memcpy(m_data.abySkill, row[5], sizeof(BYTE) * GUILD_SKILL_COUNT);
    	else
    		memset(m_data.abySkill, 0, sizeof(BYTE) * GUILD_SKILL_COUNT);
    
    	m_data.power = MAX(0, strtoul(row[6], (char **) NULL, 10));
    
    	str_to_number(m_data.ladder_point, row[7]);
    
    	if (m_data.ladder_point < 0)
    		m_data.ladder_point = 0;
    
    	str_to_number(m_data.win, row[8]);
    	str_to_number(m_data.draw, row[9]);
    	str_to_number(m_data.loss, row[10]);
    	str_to_number(m_data.gold, row[11]);
    
    	ComputeGuildPoints();
    }
    
    void CGuild::Load(DWORD guild_id)
    {
    	Initialize();
    
    	m_data.guild_id = guild_id;
    
    	DBManager::instance().FuncQuery([this](auto&& data) { return this->LoadGuildData(data); }, 
    			"SELECT master, level, exp, name, skill_point, skill, sp, ladder_point, win, draw, loss, gold FROM guild%s WHERE id = %u", get_table_postfix(), m_data.guild_id);
    
    	sys_log(0, "GUILD: loading guild id %12s %u", m_data.name, guild_id);
    
    	DBManager::instance().FuncQuery([this](auto&& data) { return this->LoadGuildGradeData(data); }, 
    			"SELECT grade, name, auth+0 FROM guild_grade%s WHERE guild_id = %u", get_table_postfix(), m_data.guild_id);
    
    	DBManager::instance().FuncQuery([this](auto&& data) { return this->LoadGuildMemberData(data); }, 
    			"SELECT pid, grade, is_general, offer, level, job, name FROM guild_member%s, player%s WHERE guild_id = %u and pid = id", get_table_postfix(), get_table_postfix(), guild_id);
    }
    
    void CGuild::SaveLevel()
    {
    	DBManager::instance().Query("UPDATE guild%s SET level=%d, exp=%u, skill_point=%d WHERE id = %u", get_table_postfix(), m_data.level,m_data.exp, m_data.skill_point,m_data.guild_id);
    }
    
    void CGuild::SendDBSkillUpdate(int amount)
    {
    	TPacketGuildSkillUpdate guild_skill;
    	guild_skill.guild_id = m_data.guild_id;
    	guild_skill.amount = amount;
    	guild_skill.skill_point = m_data.skill_point;
    	thecore_memcpy(guild_skill.skill_levels, m_data.abySkill, sizeof(BYTE) * GUILD_SKILL_COUNT);
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_SKILL_UPDATE, 0, &guild_skill, sizeof(guild_skill));
    }
    
    void CGuild::SaveSkill()
    {
    	char text[GUILD_SKILL_COUNT * 2 + 1];
    
    	DBManager::instance().EscapeString(text, sizeof(text), (const char *) m_data.abySkill, sizeof(m_data.abySkill));
    	DBManager::instance().Query("UPDATE guild%s SET sp = %d, skill_point=%d, skill='%s' WHERE id = %u",
    			get_table_postfix(), m_data.power, m_data.skill_point, text, m_data.guild_id);
    }
    
    TGuildMember* CGuild::GetMember(DWORD pid)
    {
    	TGuildMemberContainer::iterator it = m_member.find(pid);
    	if (it==m_member.end())
    		return NULL;
    
    	return &it->second;
    }
    
    DWORD CGuild::GetMemberPID(const std::string& strName)
    {
    	for ( TGuildMemberContainer::iterator iter = m_member.begin();
    			iter != m_member.end(); iter++ )
    	{
    		if ( iter->second.name == strName ) return iter->first;
    	}
    
    	return 0;
    }
    
    void CGuild::__P2PUpdateGrade(SQLMsg* pmsg)
    {
    	if (pmsg->Get()->uiNumRows)
    	{
    		MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
    		
    		int grade = 0;
    		const char* name = row[1];
    		int auth = 0;
    
    		str_to_number(grade, row[0]);
    		str_to_number(auth, row[2]);
    
    		if (grade <= 0)
    			return;
    
    		grade--;
    
    		// µξ±ή ΈνΔΐΜ ΗφΐηΏΝ ΄ΩΈ£΄ΩΈι Ύχµ¥ΐΜΖ®
    		if (0 != strcmp(m_data.grade_array[grade].grade_name, name))
    		{
    			strlcpy(m_data.grade_array[grade].grade_name, name, sizeof(m_data.grade_array[grade].grade_name));
    
    			TPacketGCGuild pack;
    			
    			pack.header = HEADER_GC_GUILD;
    			pack.size = sizeof(pack);
    			pack.subheader = GUILD_SUBHEADER_GC_GRADE_NAME;
    
    			TOneGradeNamePacket pack2;
    
    			pack.size += sizeof(pack2);
    			pack2.grade = grade + 1;
    			strlcpy(pack2.grade_name, name, sizeof(pack2.grade_name));
    
    			TEMP_BUFFER buf;
    
    			buf.write(&pack,sizeof(pack));
    			buf.write(&pack2,sizeof(pack2));
    
    			for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!=m_memberOnline.end(); ++it)
    			{
    				LPDESC d = (*it)->GetDesc();
    
    				if (d)
    					d->Packet(buf.read_peek(), buf.size());
    			}
    		}
    
    		if (m_data.grade_array[grade].auth_flag != auth)
    		{
    			m_data.grade_array[grade].auth_flag = auth;
    
    			TPacketGCGuild pack;
    			pack.header = HEADER_GC_GUILD;
    			pack.size = sizeof(pack);
    			pack.subheader = GUILD_SUBHEADER_GC_GRADE_AUTH;
    
    			TOneGradeAuthPacket pack2;
    			pack.size+=sizeof(pack2);
    			pack2.grade = grade+1;
    			pack2.auth = auth;
    
    			TEMP_BUFFER buf;
    			buf.write(&pack,sizeof(pack));
    			buf.write(&pack2,sizeof(pack2));
    
    			for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!=m_memberOnline.end(); ++it)
    			{
    				LPDESC d = (*it)->GetDesc();
    				if (d)
    				{
    					d->Packet(buf.read_peek(), buf.size());
    				}
    			}
    		}
    	}
    }
    
    void CGuild::P2PChangeGrade(BYTE grade)
    {
    	DBManager::instance().FuncQuery([this](auto&& data) { return this->__P2PUpdateGrade(data); },
    			"SELECT grade, name, auth+0 FROM guild_grade%s WHERE guild_id = %u and grade = %d", get_table_postfix(), m_data.guild_id, grade);
    }
    
    namespace 
    {
    	struct FSendChangeGrade
    	{
    		BYTE grade;
    		TPacketGuild p;
    
    		FSendChangeGrade(DWORD guild_id, BYTE grade) : grade(grade)
    		{
    			p.dwGuild = guild_id;
    			p.dwInfo = grade;
    		}
    
    		void operator()()
    		{
    			db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_GRADE, 0, &p, sizeof(p));
    		}
    	};
    }
    
    void CGuild::ChangeGradeName(BYTE grade, const char* grade_name)
    {
    	if (grade == 1)
    		return;
    
    	if (grade < 1 || grade > 15)
    	{
    		sys_err("Wrong guild grade value %d", grade);
    		return;
    	}
    
    	if (strlen(grade_name) > GUILD_NAME_MAX_LEN)
    		return;
    
    	if (!*grade_name)
    		return;
    
    	char text[GUILD_NAME_MAX_LEN * 2 + 1];
    
    	DBManager::instance().EscapeString(text, sizeof(text), grade_name, strlen(grade_name));
    	DBManager::instance().FuncAfterQuery(FSendChangeGrade(GetID(), grade), "UPDATE guild_grade%s SET name = '%s' where guild_id = %u and grade = %d", get_table_postfix(), text, m_data.guild_id, grade);
    
    	grade--;
    	strlcpy(m_data.grade_array[grade].grade_name, grade_name, sizeof(m_data.grade_array[grade].grade_name));
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack);
    	pack.subheader = GUILD_SUBHEADER_GC_GRADE_NAME;
    
    	TOneGradeNamePacket pack2;
    	pack.size+=sizeof(pack2);
    	pack2.grade = grade+1;
    	strlcpy(pack2.grade_name,grade_name, sizeof(pack2.grade_name));
    
    	TEMP_BUFFER buf;
    	buf.write(&pack,sizeof(pack));
    	buf.write(&pack2,sizeof(pack2));
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!=m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    
    		if (d)
    			d->Packet(buf.read_peek(), buf.size());
    	}
    }
    
    void CGuild::ChangeGradeAuth(BYTE grade, BYTE auth)
    {
    	if (grade == 1)
    		return;
    
    	if (grade < 1 || grade > 15)
    	{
    		sys_err("Wrong guild grade value %d", grade);
    		return;
    	}
    
    	DBManager::instance().FuncAfterQuery(FSendChangeGrade(GetID(),grade), "UPDATE guild_grade%s SET auth = %d where guild_id = %u and grade = %d", get_table_postfix(), auth, m_data.guild_id, grade);
    
    	grade--;
    
    	m_data.grade_array[grade].auth_flag=auth;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack);
    	pack.subheader = GUILD_SUBHEADER_GC_GRADE_AUTH;
    
    	TOneGradeAuthPacket pack2;
    	pack.size += sizeof(pack2);
    	pack2.grade = grade + 1;
    	pack2.auth = auth;
    
    	TEMP_BUFFER buf;
    	buf.write(&pack, sizeof(pack));
    	buf.write(&pack2, sizeof(pack2));
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    
    		if (d)
    			d->Packet(buf.read_peek(), buf.size());
    	}
    }
    
    void CGuild::SendGuildInfoPacket(LPCHARACTER ch)
    {
    	LPDESC d = ch->GetDesc();
    
    	if (!d)
    		return;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(TPacketGCGuild) + sizeof(TPacketGCGuildInfo);
    	pack.subheader = GUILD_SUBHEADER_GC_INFO;
    
    	TPacketGCGuildInfo pack_sub;
    
    	memset(&pack_sub, 0, sizeof(TPacketGCGuildInfo));
    	pack_sub.member_count = GetMemberCount(); 
    	pack_sub.max_member_count = GetMaxMemberCount();
    	pack_sub.guild_id = m_data.guild_id;
    	pack_sub.master_pid = m_data.master_pid;
    	pack_sub.exp	= m_data.exp;
    	pack_sub.level	= m_data.level;
    	strlcpy(pack_sub.name, m_data.name, sizeof(pack_sub.name));
    	pack_sub.gold	= m_data.gold;
    	pack_sub.has_land	= HasLand();
    
    	sys_log(0, "GMC guild_name %s", m_data.name);
    	sys_log(0, "GMC master %d", m_data.master_pid);
    
    	d->BufferedPacket(&pack, sizeof(TPacketGCGuild));
    	d->Packet(&pack_sub, sizeof(TPacketGCGuildInfo));
    }
    
    bool CGuild::OfferExp(LPCHARACTER ch, int amount)
    {
    	TGuildMemberContainer::iterator cit = m_member.find(ch->GetPlayerID());
    
    	if (cit == m_member.end())
    		return false;
    
    	if (m_data.exp+amount < m_data.exp)
    		return false;
    
    	if (amount < 0)
    		return false;
    
    	if (ch->GetExp() < (DWORD) amount)
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Α¦°ψΗΟ°νΐΪ Ηϴ °ζΗθΔ΅°΅ ³²ΐΊ °ζΗθΔ΅ΊΈ΄Ω ΈΉ½ΐ΄Ο΄Ω."));
    		return false;
    	}
    
    	if (ch->GetExp() - (DWORD) amount > ch->GetExp())
    	{
    		sys_err("Wrong guild offer amount %d by %s[%u]", amount, ch->GetName(), ch->GetPlayerID());
    		return false;
    	}
    
    	ch->PointChange(POINT_EXP, -amount);
    
    	TPacketGuildExpUpdate guild_exp;
    	guild_exp.guild_id = GetID();
    	guild_exp.amount = amount / 100;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_EXP_UPDATE, 0, &guild_exp, sizeof(guild_exp));
    	GuildPointChange(POINT_EXP, amount / 100, true);
    
    	cit->second.offer_exp += amount / 100;
    	cit->second._dummy = 0;
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    		if (d)
    		{
    			pack.subheader = GUILD_SUBHEADER_GC_LIST;
    			pack.size = sizeof(pack) + 13;
    			d->BufferedPacket(&pack, sizeof(pack));
    			d->Packet(&(cit->second), sizeof(DWORD) * 3 + 1);
    		}
    	}
    
    	SaveMember(ch->GetPlayerID());
    
    	TPacketGuildChangeMemberData gd_guild;
    
    	gd_guild.guild_id = GetID();
    	gd_guild.pid = ch->GetPlayerID();
    	gd_guild.offer = cit->second.offer_exp;
    	gd_guild.level = ch->GetLevel();
    	gd_guild.grade = cit->second.grade;
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild));
    	return true;
    }
    
    void CGuild::Disband()
    {
    	sys_log(0, "GUILD: Disband %s:%u", GetName(), GetID());
    
    	//building::CLand* pLand = building::CManager::instance().FindLandByGuild(GetID());
    	//if (pLand)
    	//pLand->SetOwner(0);
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPCHARACTER ch = *it;
    		ch->SetGuild(NULL);
    		SendOnlineRemoveOnePacket(ch->GetPlayerID());
    		ch->SetQuestFlag("guild_manage.new_withdraw_time", get_global_time());
    	}
    
    	for (TGuildMemberContainer::iterator it = m_member.begin(); it != m_member.end(); ++it)
    	{
    		CGuildManager::instance().Unlink(it->first);
    	}
    
    }
    
    void CGuild::RequestDisband(DWORD pid)
    {
    	if (m_data.master_pid != pid)
    		return;
    
    	TPacketGuild gd_guild;
    	gd_guild.dwGuild = GetID();
    	gd_guild.dwInfo = 0;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_DISBAND, 0, &gd_guild, sizeof(TPacketGuild));
    
    	// LAND_CLEAR
    	building::CManager::instance().ClearLandByGuildID(GetID());
    	// END_LAND_CLEAR
    }
    
    void CGuild::AddComment(LPCHARACTER ch, const std::string& str)
    {
    	int player_id = ch->GetPlayerID();
    
    	if (str.length() > GUILD_COMMENT_MAX_LEN)
    		return;
    
    	char text[GUILD_COMMENT_MAX_LEN * 2 + 1];
    	DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length());
    
    	DBManager::instance().FuncAfterQuery([this, player_id] { return this->RefreshCommentForce(player_id); },
    			"INSERT INTO guild_comment%s(guild_id, name, notice, content, time) VALUES(%u, '%s', %d, '%s', NOW())", 
    			get_table_postfix(), m_data.guild_id, ch->GetName(), (str[0] == '!') ? 1 : 0, text);
    }
    
    void CGuild::DeleteComment(LPCHARACTER ch, DWORD comment_id)
    {
    	SQLMsg * pmsg;
    
    	if (GetMember(ch->GetPlayerID())->grade == GUILD_LEADER_GRADE)
    		pmsg = DBManager::instance().DirectQuery("DELETE FROM guild_comment%s WHERE id = %u AND guild_id = %u",get_table_postfix(), comment_id, m_data.guild_id);
    	else
    		pmsg = DBManager::instance().DirectQuery("DELETE FROM guild_comment%s WHERE id = %u AND guild_id = %u AND name = '%s'",get_table_postfix(), comment_id, m_data.guild_id, ch->GetName());
    
    	if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1)
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »θΑ¦Η Όφ Ύψ΄Β ±ΫΐΤ΄Ο΄Ω."));
    	else
    		RefreshCommentForce(ch->GetPlayerID());
    
    	M2_DELETE(pmsg);
    }
    
    void CGuild::RefreshComment(LPCHARACTER ch)
    {
    	RefreshCommentForce(ch->GetPlayerID());
    }
    
    void CGuild::RefreshCommentForce(DWORD player_id)
    {
    	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(player_id);
    	if (ch == NULL) {
    		return;
    	}
    
    	std::unique_ptr<SQLMsg> pmsg (DBManager::instance().DirectQuery("SELECT id, name, content FROM guild_comment%s WHERE guild_id = %u ORDER BY notice DESC, id DESC LIMIT %d", get_table_postfix(), m_data.guild_id, GUILD_COMMENT_MAX_COUNT));
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+1;
    	pack.subheader = GUILD_SUBHEADER_GC_COMMENTS;
    
    	BYTE count = pmsg->Get()->uiNumRows;
    
    	LPDESC d = ch->GetDesc();
    
    	if (!d) 
    		return;
    
    	pack.size += (sizeof(DWORD)+CHARACTER_NAME_MAX_LEN+1+GUILD_COMMENT_MAX_LEN+1)*(WORD)count;
    	d->BufferedPacket(&pack,sizeof(pack));
    	d->BufferedPacket(&count, 1);
    	char szName[CHARACTER_NAME_MAX_LEN + 1];
    	char szContent[GUILD_COMMENT_MAX_LEN + 1];
    	memset(szName, 0, sizeof(szName));
    	memset(szContent, 0, sizeof(szContent));
    
    	for (uint i = 0; i < pmsg->Get()->uiNumRows; i++)
    	{
    		MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
    		DWORD id = strtoul(row[0], NULL, 10);
    
    		strlcpy(szName, row[1], sizeof(szName));
    		strlcpy(szContent, row[2], sizeof(szContent));
    
    		d->BufferedPacket(&id, sizeof(id));
    		d->BufferedPacket(szName, sizeof(szName));
    
    		if (i == pmsg->Get()->uiNumRows - 1)
    			d->Packet(szContent, sizeof(szContent)); // Έ¶ΑφΈ· ΑΩΐΜΈι ΊΈ³»±β
    		else
    			d->BufferedPacket(szContent, sizeof(szContent));
    	}
    }
    
    bool CGuild::ChangeMemberGeneral(DWORD pid, BYTE is_general)
    {
    	if (is_general && GetGeneralCount() >= GetMaxGeneralCount())
    		return false;
    
    	TGuildMemberContainer::iterator it = m_member.find(pid);
    	if (it == m_member.end())
    	{
    		return true;
    	}
    
    	is_general = is_general?1:0;
    
    	if (it->second.is_general == is_general)
    		return true;
    
    	if (is_general)
    		++m_general_count;
    	else
    		--m_general_count;
    
    	it->second.is_general = is_general;
    
    	TGuildMemberOnlineContainer::iterator itOnline = m_memberOnline.begin();
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+5;
    	pack.subheader = GUILD_SUBHEADER_GC_CHANGE_MEMBER_GENERAL;
    
    	while (itOnline != m_memberOnline.end())
    	{
    		LPDESC d = (*(itOnline++))->GetDesc();
    
    		if (!d)
    			continue;
    
    		d->BufferedPacket(&pack, sizeof(pack));
    		d->BufferedPacket(&pid, sizeof(pid));
    		d->Packet(&is_general, sizeof(is_general));
    	}
    
    	SaveMember(pid);
    	return true;
    }
    
    void CGuild::ChangeMemberGrade(DWORD pid, BYTE grade)
    {
    	if (grade == 1)
    		return;
    
    	TGuildMemberContainer::iterator it = m_member.find(pid);
    
    	if (it == m_member.end())
    		return;
    
    	it->second.grade = grade;
    
    	TGuildMemberOnlineContainer::iterator itOnline = m_memberOnline.begin();
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	pack.size = sizeof(pack)+5;
    	pack.subheader = GUILD_SUBHEADER_GC_CHANGE_MEMBER_GRADE;
    
    	while (itOnline != m_memberOnline.end())
    	{
    		LPDESC d = (*(itOnline++))->GetDesc();
    
    		if (!d)
    			continue;
    
    		d->BufferedPacket(&pack, sizeof(pack));
    		d->BufferedPacket(&pid, sizeof(pid));
    		d->Packet(&grade, sizeof(grade));
    	}
    
    	SaveMember(pid);
    
    	TPacketGuildChangeMemberData gd_guild;
    
    	gd_guild.guild_id = GetID();
    	gd_guild.pid = pid;
    	gd_guild.offer = it->second.offer_exp;
    	gd_guild.level = it->second.level;
    	gd_guild.grade = grade;
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild));
    }
    
    void CGuild::SkillLevelUp(DWORD dwVnum)
    {
    	DWORD dwRealVnum = dwVnum - GUILD_SKILL_START;
    
    	if (dwRealVnum >= GUILD_SKILL_COUNT)
    		return;
    
    	CSkillProto* pkSk = CSkillManager::instance().Get(dwVnum);
    
    	if (!pkSk)
    	{
    		sys_err("There is no such guild skill by number %u", dwVnum);
    		return;
    	}
    
    	if (m_data.abySkill[dwRealVnum] >= pkSk->bMaxLevel)
    		return;
    
    	if (m_data.skill_point <= 0)
    		return;
    	m_data.skill_point --;
    
    	m_data.abySkill[dwRealVnum] ++;
    
    	ComputeGuildPoints();
    	SaveSkill();
    	SendDBSkillUpdate();
    
    	/*switch (dwVnum)
    	  {
    	  case GUILD_SKILL_GAHO:
    	  {
    	  TGuildMemberOnlineContainer::iterator it;
    
    	  for (it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	  (*it)->PointChange(POINT_DEF_GRADE, 1);
    	  }
    	  break;
    	  case GUILD_SKILL_HIM:
    	  {
    	  TGuildMemberOnlineContainer::iterator it;
    
    	  for (it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	  (*it)->PointChange(POINT_ATT_GRADE, 1);
    	  }
    	  break;
    	  }*/
    
    	for_each(m_memberOnline.begin(), m_memberOnline.end(), [*this](auto&& data) { return this->SendSkillInfoPacket(data); });
    
    	sys_log(0, "Guild SkillUp: %s %d level %d type %u", GetName(), pkSk->dwVnum, m_data.abySkill[dwRealVnum], pkSk->dwType);
    }
    
    void CGuild::UseSkill(DWORD dwVnum, LPCHARACTER ch, DWORD pid)
    {
    	LPCHARACTER victim = NULL;
    
    	if (!GetMember(ch->GetPlayerID()) || !HasGradeAuth(GetMember(ch->GetPlayerID())->grade, GUILD_AUTH_USE_SKILL))
    		return;
    
    	sys_log(0,"GUILD_USE_SKILL : cname(%s), skill(%d)", ch ? ch->GetName() : "", dwVnum);
    
    	DWORD dwRealVnum = dwVnum - GUILD_SKILL_START;
    
    	if (!ch->CanMove())
    		return;
    
    	if (dwRealVnum >= GUILD_SKILL_COUNT)
    		return;
    
    	CSkillProto* pkSk = CSkillManager::instance().Get(dwVnum);
    
    	if (!pkSk)
    	{
    		sys_err("There is no such guild skill by number %u", dwVnum);
    		return;
    	}
    
    	if (m_data.abySkill[dwRealVnum] == 0)
    		return;
    
    	if ((pkSk->dwFlag & SKILL_FLAG_SELFONLY))
    	{
    		// ΐΜΉΜ °Ι·Α ΐΦΐΈΉΗ·Ξ »ηΏλΗΟΑφ ΎΚΐ½.
    		if (ch->FindAffect(pkSk->dwVnum))
    			return;
    
    		victim = ch;
    	}
    
    	if (ch->IsAffectFlag(AFF_REVIVE_INVISIBLE))
    		ch->RemoveAffect(AFFECT_REVIVE_INVISIBLE);
    
    	if (ch->IsAffectFlag(AFF_EUNHYUNG))
    		ch->RemoveAffect(SKILL_EUNHYUNG);
    
    	double k =1.0*m_data.abySkill[dwRealVnum]/pkSk->bMaxLevel;
    	pkSk->kSPCostPoly.SetVar("k", k);
    	int iNeededSP = (int) pkSk->kSPCostPoly.Eval();
    
    	if (GetSP() < iNeededSP)
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Ώλ½Ε·ΒΐΜ ΊΞΑ·ΗΥ΄Ο΄Ω. (%d, %d)"), GetSP(), iNeededSP);
    		return;
    	}
    
    	pkSk->kCooldownPoly.SetVar("k", k);
    	int iCooltime = (int) pkSk->kCooldownPoly.Eval();
    
    	if (!abSkillUsable[dwRealVnum])
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΔπΕΈΐΣΐΜ ³΅³Αφ ΎΚΎΖ ±ζµε ½ΊΕ³ΐ» »ηΏλΗ Όφ Ύψ½ΐ΄Ο΄Ω."));
    		return;
    	}
    
    	{
    		TPacketGuildUseSkill p;
    		p.dwGuild = GetID();
    		p.dwSkillVnum = pkSk->dwVnum;
    		p.dwCooltime = iCooltime;
    		db_clientdesc->DBPacket(HEADER_GD_GUILD_USE_SKILL, 0, &p, sizeof(p));
    	}
    	abSkillUsable[dwRealVnum] = false;
    	//abSkillUsed[dwRealVnum] = true;
    	//adwSkillNextUseTime[dwRealVnum] = get_dword_time() + iCooltime * 1000;
    
    	//PointChange(POINT_SP, -iNeededSP);
    	//GuildPointChange(POINT_SP, -iNeededSP);
    
    	if (test_server)
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> %d ½ΊΕ³ΐ» »ηΏλΗΤ (%d, %d) to %u"), dwVnum, GetSP(), iNeededSP, pid);
    
    	switch (dwVnum)
    	{
    		case GUILD_SKILL_TELEPORT:
    			// Ηφΐη Ό­ΉφΏ΅ ΐΦ΄Β »η¶χΐ» ΈΥΐϊ ½Γµµ.
    			SendDBSkillUpdate(-iNeededSP);
    			if ((victim = (CHARACTER_MANAGER::instance().FindByPID(pid))))
    				ch->WarpSet(victim->GetX(), victim->GetY());
    			else
    			{
    				if (m_memberP2POnline.find(pid) != m_memberP2POnline.end())
    				{
    					// ΄ΩΈ¥ Ό­ΉφΏ΅ ·Ξ±ΧΐΞµΘ »η¶χΐΜ ΐΦΐ½ -> Έή½ΓΑφ ΊΈ³» ΑΒΗ¥Έ¦ ΉήΎΖΏΐΐΪ
    					// 1. A.pid, B.pid Έ¦ »ΡΈ²
    					// 2. B.pidΈ¦ °΅Αψ Ό­Ήφ°΅ »ΡΈ°Ό­ΉφΏ΅°Τ A.pid, ΑΒΗ¥ Έ¦ ΊΈ³Ώ
    					// 3. ΏφΗΑ
    					CCI * pcci = P2P_MANAGER::instance().FindByPID(pid);
    
    					if (pcci->bChannel != g_bChannel)
    					{
    						ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λ°΅ %d Γ¤³ΞΏ΅ ΐΦ½ΐ΄Ο΄Ω. (Ηφΐη Γ¤³Ξ %d)"), pcci->bChannel, g_bChannel);
    					}
    					else
    					{
    						TPacketGGFindPosition p;
    						p.header = HEADER_GG_FIND_POSITION;
    						p.dwFromPID = ch->GetPlayerID();
    						p.dwTargetPID = pid;
    						pcci->pkDesc->Packet(&p, sizeof(TPacketGGFindPosition));
    						if (test_server) ch->ChatPacket(CHAT_TYPE_PARTY, "sent find position packet for guild teleport");
    					}
    				}
    				else
    					ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λ°΅ ΏΒ¶σΐΞ »σΕΒ°΅ ΎΖ΄Υ΄Ο΄Ω."));
    			}
    			break;
    
    			/*case GUILD_SKILL_ACCEL:
    			  ch->RemoveAffect(dwVnum);
    			  ch->AddAffect(dwVnum, POINT_MOV_SPEED, m_data.abySkill[dwRealVnum]*3, pkSk->dwAffectFlag, (int)pkSk->kDurationPoly.Eval(), 0, false);
    			  ch->AddAffect(dwVnum, POINT_ATT_SPEED, m_data.abySkill[dwRealVnum]*3, pkSk->dwAffectFlag, (int)pkSk->kDurationPoly.Eval(), 0, false);
    			  break;*/
    
    		default:
    			{
    				/*if (ch->GetPlayerID() != GetMasterPID())
    				  {
    				  ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ±ζµεΐεΈΈ ±ζµε ½ΊΕ³ΐ» »ηΏλΗ Όφ ΐΦ½ΐ΄Ο΄Ω."));
    				  return;
    				  }*/
    
    				if (!UnderAnyWar())
    				{
    					ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ±ζµε ½ΊΕ³ΐΊ ±ζµεΐό ΑίΏ΅ΈΈ »ηΏλΗ Όφ ΐΦ½ΐ΄Ο΄Ω."));
    					return;
    				}
    
    				SendDBSkillUpdate(-iNeededSP);
    
    				for (itertype(m_memberOnline) it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    				{
    					LPCHARACTER victim = *it;
    					victim->RemoveAffect(dwVnum);
    					ch->ComputeSkill(dwVnum, victim, m_data.abySkill[dwRealVnum]);
    				}
    			}
    			break;
    			/*if (!victim)
    			  return;
    
    			  ch->ComputeSkill(dwVnum, victim, m_data.abySkill[dwRealVnum]);*/
    	}
    }
    
    void CGuild::SendSkillInfoPacket(LPCHARACTER ch) const
    {
    	LPDESC d = ch->GetDesc();
    
    	if (!d)
    		return;
    
    	TPacketGCGuild pack;
    
    	pack.header		= HEADER_GC_GUILD;
    	pack.size		= sizeof(pack) + 6 + GUILD_SKILL_COUNT;
    	pack.subheader	= GUILD_SUBHEADER_GC_SKILL_INFO;
    
    	d->BufferedPacket(&pack, sizeof(pack));
    	d->BufferedPacket(&m_data.skill_point,	1);
    	d->BufferedPacket(&m_data.abySkill,		GUILD_SKILL_COUNT);
    	d->BufferedPacket(&m_data.power,		2);
    	d->Packet(&m_data.max_power,	2);
    }
    
    void CGuild::ComputeGuildPoints()
    {
    	m_data.max_power = GUILD_BASE_POWER + (m_data.level-1) * GUILD_POWER_PER_LEVEL;
    
    	m_data.power = MINMAX(0, m_data.power, m_data.max_power);
    }
    
    int CGuild::GetSkillLevel(DWORD vnum)
    {
    	DWORD dwRealVnum = vnum - GUILD_SKILL_START;
    
    	if (dwRealVnum >= GUILD_SKILL_COUNT)
    		return 0;
    
    	return m_data.abySkill[dwRealVnum];
    }
    
    /*void CGuild::GuildUpdateAffect(LPCHARACTER ch)
      {
      if (GetSkillLevel(GUILD_SKILL_GAHO))
      ch->PointChange(POINT_DEF_GRADE, GetSkillLevel(GUILD_SKILL_GAHO));
    
      if (GetSkillLevel(GUILD_SKILL_HIM))
      ch->PointChange(POINT_ATT_GRADE, GetSkillLevel(GUILD_SKILL_HIM));
      }*/
    
    /*void CGuild::GuildRemoveAffect(LPCHARACTER ch)
      {
      if (GetSkillLevel(GUILD_SKILL_GAHO))
      ch->PointChange(POINT_DEF_GRADE, -(int) GetSkillLevel(GUILD_SKILL_GAHO));
    
      if (GetSkillLevel(GUILD_SKILL_HIM))
      ch->PointChange(POINT_ATT_GRADE, -(int) GetSkillLevel(GUILD_SKILL_HIM));
      }*/
    
    void CGuild::UpdateSkill(BYTE skill_point, BYTE* skill_levels)
    {
    	//int iDefMoreBonus = 0;
    	//int iAttMoreBonus = 0;
    
    	m_data.skill_point = skill_point;
    	/*if (skill_levels[GUILD_SKILL_GAHO - GUILD_SKILL_START]!=GetSkillLevel(GUILD_SKILL_GAHO))
    	  {
    	  iDefMoreBonus = skill_levels[GUILD_SKILL_GAHO - GUILD_SKILL_START]-GetSkillLevel(GUILD_SKILL_GAHO);
    	  }
    	  if (skill_levels[GUILD_SKILL_HIM - GUILD_SKILL_START]!=GetSkillLevel(GUILD_SKILL_HIM))
    	  {
    	  iAttMoreBonus = skill_levels[GUILD_SKILL_HIM  - GUILD_SKILL_START]-GetSkillLevel(GUILD_SKILL_HIM);
    	  }
    
    	  if (iDefMoreBonus || iAttMoreBonus)
    	  {
    	  for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	  {
    	  (*it)->PointChange(POINT_ATT_GRADE, iAttMoreBonus);
    	  (*it)->PointChange(POINT_DEF_GRADE, iDefMoreBonus);
    	  }
    	  }*/
    
    	thecore_memcpy(m_data.abySkill, skill_levels, sizeof(BYTE) * GUILD_SKILL_COUNT);
    	ComputeGuildPoints();
    }
    
    static DWORD __guild_levelup_exp(int level)
    {
    	return guild_exp_table[level];
    }
    
    void CGuild::GuildPointChange(BYTE type, int amount, bool save)
    {
    	switch (type)
    	{
    		case POINT_SP:
    			m_data.power += amount;
    
    			m_data.power = MINMAX(0, m_data.power, m_data.max_power);
    
    			if (save)
    			{
    				SaveSkill();
    			}
    
    			for_each(m_memberOnline.begin(), m_memberOnline.end(), [*this](auto&& data) { return this->SendSkillInfoPacket(data); });
    			break;
    
    		case POINT_EXP:
    			if (amount < 0 && m_data.exp < (DWORD) - amount)
    			{
    				m_data.exp = 0;
    			}
    			else
    			{
    				m_data.exp += amount;
    
    				while (m_data.exp >= __guild_levelup_exp(m_data.level))
    				{
    
    					if (m_data.level < gguild_max_level)
    					{
    						m_data.exp -= __guild_levelup_exp(m_data.level);
    						++m_data.level;
    						++m_data.skill_point;
    
    						if (m_data.level > gguild_max_level)
    							m_data.level = gguild_max_level;
    
    						ComputeGuildPoints();
    						GuildPointChange(POINT_SP, m_data.max_power-m_data.power);
    
    						if (save)
    							ChangeLadderPoint(GUILD_LADDER_POINT_PER_LEVEL);
    
    						// NOTIFY_GUILD_EXP_CHANGE
    						for_each(m_memberOnline.begin(), m_memberOnline.end(), [this](auto&& data) { return this->SendGuildInfoPacket(data); });
    						// END_OF_NOTIFY_GUILD_EXP_CHANGE
    					}
    
    					if (m_data.level == gguild_max_level)
    					{
    						m_data.exp = 0;
    					}
    				}
    			}
    
    			TPacketGCGuild pack;
    			pack.header = HEADER_GC_GUILD;
    			pack.size = sizeof(pack)+5;
    			pack.subheader = GUILD_SUBHEADER_GC_CHANGE_EXP;
    
    			TEMP_BUFFER buf;
    			buf.write(&pack,sizeof(pack));
    			buf.write(&m_data.level,1);
    			buf.write(&m_data.exp,4);
    
    			for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    			{
    				LPDESC d = (*it)->GetDesc();
    
    				if (d)
    					d->Packet(buf.read_peek(), buf.size());
    			}
    
    			if (save)
    				SaveLevel();
    
    			break;
    	}
    }
    
    void CGuild::SkillRecharge()
    {
    	//GuildPointChange(POINT_SP, m_data.max_power / 2);
    	//GuildPointChange(POINT_SP, 10);
    }
    
    void CGuild::SaveMember(DWORD pid)
    {
    	TGuildMemberContainer::iterator it = m_member.find(pid);
    
    	if (it == m_member.end())
    		return;
    
    	DBManager::instance().Query(
    			"UPDATE guild_member%s SET grade = %d, offer = %u, is_general = %d WHERE pid = %u and guild_id = %u",
    			get_table_postfix(), it->second.grade, it->second.offer_exp, it->second.is_general, pid, m_data.guild_id);
    }
    
    void CGuild::LevelChange(DWORD pid, BYTE level)
    {
    	TGuildMemberContainer::iterator cit = m_member.find(pid);
    
    	if (cit == m_member.end())
    		return;
    
    	cit->second.level = level;
    
    	TPacketGuildChangeMemberData gd_guild;
    
    	gd_guild.guild_id = GetID();
    	gd_guild.pid = pid;
    	gd_guild.offer = cit->second.offer_exp;
    	gd_guild.grade = cit->second.grade;
    	gd_guild.level = level;
    
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild));
    
    	TPacketGCGuild pack;
    	pack.header = HEADER_GC_GUILD;
    	cit->second._dummy = 0;
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    
    		if (d)
    		{
    			pack.subheader = GUILD_SUBHEADER_GC_LIST;
    			pack.size = sizeof(pack) + 13;
    			d->BufferedPacket(&pack, sizeof(pack));
    			d->Packet(&(cit->second), sizeof(DWORD) * 3 + 1);
    		}
    	}
    }
    
    void CGuild::ChangeMemberData(DWORD pid, DWORD offer, BYTE level, BYTE grade)
    {
    	TGuildMemberContainer::iterator cit = m_member.find(pid);
    
    	if (cit == m_member.end())
    		return;
    
    	cit->second.offer_exp = offer;
    	cit->second.level = level;
    	cit->second.grade = grade;
    	cit->second._dummy = 0;
    
    	TPacketGCGuild pack;
    	memset(&pack, 0, sizeof(pack));
    	pack.header = HEADER_GC_GUILD;
    
    	for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    		if (d)
    		{
    			pack.subheader = GUILD_SUBHEADER_GC_LIST;
    			pack.size = sizeof(pack) + 13;
    			d->BufferedPacket(&pack, sizeof(pack));
    			d->Packet(&(cit->second), sizeof(DWORD) * 3 + 1);
    		}
    	}
    }
    
    namespace
    {
    	struct FGuildChat
    	{
    		const char* c_pszText;
    
    		FGuildChat(const char* c_pszText)
    			: c_pszText(c_pszText)
    			{}
    
    		void operator()(LPCHARACTER ch)
    		{
    			ch->ChatPacket(CHAT_TYPE_GUILD, "%s", c_pszText);
    		}
    	};
    }
    
    void CGuild::P2PChat(const char* c_pszText)
    {
    	std::for_each(m_memberOnline.begin(), m_memberOnline.end(), FGuildChat(c_pszText));
    }
    
    void CGuild::Chat(const char* c_pszText)
    {
    	std::for_each(m_memberOnline.begin(), m_memberOnline.end(), FGuildChat(c_pszText));
    
    	TPacketGGGuild p1;
    	TPacketGGGuildChat p2;
    
    	p1.bHeader = HEADER_GG_GUILD;
    	p1.bSubHeader = GUILD_SUBHEADER_GG_CHAT;
    	p1.dwGuild = GetID();
    	strlcpy(p2.szText, c_pszText, sizeof(p2.szText));
    
    	P2P_MANAGER::instance().Send(&p1, sizeof(TPacketGGGuild));
    	P2P_MANAGER::instance().Send(&p2, sizeof(TPacketGGGuildChat));
    }
    
    LPCHARACTER CGuild::GetMasterCharacter()
    { 
    	return CHARACTER_MANAGER::instance().FindByPID(GetMasterPID()); 
    }
    
    void CGuild::Packet(const void* buf, int size)
    {
    	for (itertype(m_memberOnline) it = m_memberOnline.begin(); it!=m_memberOnline.end();++it)
    	{
    		LPDESC d = (*it)->GetDesc();
    
    		if (d)
    			d->Packet(buf, size);
    	}
    }
    
    int CGuild::GetTotalLevel() const
    {
    	int total = 0;
    
    	for (itertype(m_member) it = m_member.begin(); it != m_member.end(); ++it)
    	{
    		total += it->second.level;
    	}
    
    	return total;
    }
    
    bool CGuild::ChargeSP(LPCHARACTER ch, int iSP)
    {
    	int gold = iSP * 100;
    
    	if (gold < iSP || ch->GetGold() < (long long)gold)
    		return false;
    
    	int iRemainSP = m_data.max_power - m_data.power;
    
    	if (iSP > iRemainSP)
    	{
    		iSP = iRemainSP;
    		gold = iSP * 100;
    	}
    
    	ch->PointChange(POINT_GOLD, -gold);
    	DBManager::instance().SendMoneyLog(MONEY_LOG_GUILD, 1, -gold);
    
    	SendDBSkillUpdate(iSP);
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> %uΐΗ Ώλ½Ε·Βΐ» ΘΈΊΉΗΟΏ΄½ΐ΄Ο΄Ω."), iSP);
    	}
    	return true;
    }
    
    void CGuild::SkillUsableChange(DWORD dwSkillVnum, bool bUsable)
    {
    	DWORD dwRealVnum = dwSkillVnum - GUILD_SKILL_START;
    
    	if (dwRealVnum >= GUILD_SKILL_COUNT)
    		return; 
    
    	abSkillUsable[dwRealVnum] = bUsable;
    
    	// GUILD_SKILL_COOLTIME_BUG_FIX
    	sys_log(0, "CGuild::SkillUsableChange(guild=%s, skill=%d, usable=%d)", GetName(), dwSkillVnum, bUsable);
    	// END_OF_GUILD_SKILL_COOLTIME_BUG_FIX
    }
    
    // GUILD_MEMBER_COUNT_BONUS
    void CGuild::SetMemberCountBonus(int iBonus)
    {
    	m_iMemberCountBonus = iBonus;
    	sys_log(0, "GUILD_IS_FULL_BUG : Bonus set to %d(val:%d)", iBonus, m_iMemberCountBonus);
    }
    
    void CGuild::BroadcastMemberCountBonus()
    {
    	TPacketGGGuild p1;
    
    	p1.bHeader = HEADER_GG_GUILD;
    	p1.bSubHeader = GUILD_SUBHEADER_GG_SET_MEMBER_COUNT_BONUS;
    	p1.dwGuild = GetID();
    
    	P2P_MANAGER::instance().Send(&p1, sizeof(TPacketGGGuild));
    	P2P_MANAGER::instance().Send(&m_iMemberCountBonus, sizeof(int));
    }
    
    int CGuild::GetMaxMemberCount()
    {
    	// GUILD_IS_FULL_BUG_FIX
    	if ( m_iMemberCountBonus < 0 || m_iMemberCountBonus > 18 )
    		m_iMemberCountBonus = 0;
    	// END_GUILD_IS_FULL_BUG_FIX
    
    	if ( LC_IsHongKong() == true )
    	{
    		quest::PC* pPC = quest::CQuestManager::instance().GetPC(GetMasterPID());
    
    		if ( pPC != NULL )
    		{
    			if ( pPC->GetFlag("guild.is_unlimit_member") == 1 )
    			{
    				return INT_MAX;
    			}
    		}
    	}
    
    	return 32 + 2 * (m_data.level-1) + m_iMemberCountBonus;
    }
    // END_OF_GUILD_MEMBER_COUNT_BONUS
    
    void CGuild::AdvanceLevel(int iLevel)
    {
    	if (m_data.level == iLevel)
    		return;
    
    	m_data.level = MIN(gguild_max_level, iLevel);
    }
    
    void CGuild::RequestDepositMoney(LPCHARACTER ch, int iGold)
    {
    	if (false==ch->CanDeposit())
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΐα½ΓΘΔΏ΅ ΐΜΏλΗΨΑΦ½Κ½ΓΏΐ"));
    		return;
    	}
    
    	if (ch->GetGold() < (long long)iGold)
    		return;
    
    
    	ch->PointChange(POINT_GOLD, -iGold);
    
    	TPacketGDGuildMoney p;
    	p.dwGuild = GetID();
    	p.iGold = iGold;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_DEPOSIT_MONEY, 0, &p, sizeof(p));
    
    	char buf[64+1];
    	snprintf(buf, sizeof(buf), "%u %s", GetID(), GetName());
    	LogManager::instance().CharLog(ch, iGold, "GUILD_DEPOSIT", buf);
    
    	ch->UpdateDepositPulse();
    	sys_log(0, "GUILD: DEPOSIT %s:%u player %s[%u] gold %d", GetName(), GetID(), ch->GetName(), ch->GetPlayerID(), iGold);
    }
    
    void CGuild::RequestWithdrawMoney(LPCHARACTER ch, int iGold)
    {
    	if (false==ch->CanDeposit())
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΐα½ΓΘΔΏ΅ ΐΜΏλΗΨΑΦ½Κ½ΓΏΐ"));
    		return;
    	}
    
    	if (ch->GetPlayerID() != GetMasterPID())
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ±ζµε ±έ°νΏ΅Ό± ±ζµεΐεΈΈ Γβ±έΗ Όφ ΐΦ½ΐ΄Ο΄Ω."));
    		return;
    	}
    
    	if (m_data.gold < iGold)
    	{
    		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> °΅Αφ°ν ΐΦ΄Β µ·ΐΜ ΊΞΑ·ΗΥ΄Ο΄Ω."));
    		return;
    	}
    
    	TPacketGDGuildMoney p;
    	p.dwGuild = GetID();
    	p.iGold = iGold;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_WITHDRAW_MONEY, 0, &p, sizeof(p));
    
    	ch->UpdateDepositPulse();
    }
    
    void CGuild::RecvMoneyChange(int iGold)
    {
    	m_data.gold = iGold;
    
    	TPacketGCGuild p;
    	p.header = HEADER_GC_GUILD;
    	p.size = sizeof(p) + sizeof(int);
    	p.subheader = GUILD_SUBHEADER_GC_MONEY_CHANGE;
    
    	for (itertype(m_memberOnline) it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it)
    	{
    		LPCHARACTER ch = *it;
    		LPDESC d = ch->GetDesc();
    		d->BufferedPacket(&p, sizeof(p));
    		d->Packet(&iGold, sizeof(int));
    	}
    }
    
    void CGuild::RecvWithdrawMoneyGive(int iChangeGold)
    {
    	LPCHARACTER ch = GetMasterCharacter();
    
    	if (ch)
    	{
    		ch->PointChange(POINT_GOLD, iChangeGold);
    		sys_log(0, "GUILD: WITHDRAW %s:%u player %s[%u] gold %d", GetName(), GetID(), ch->GetName(), ch->GetPlayerID(), iChangeGold);
    	}
    
    	TPacketGDGuildMoneyWithdrawGiveReply p;
    	p.dwGuild = GetID();
    	p.iChangeGold = iChangeGold;
    	p.bGiveSuccess = ch ? 1 : 0;
    	db_clientdesc->DBPacket(HEADER_GD_GUILD_WITHDRAW_MONEY_GIVE_REPLY, 0, &p, sizeof(p));
    }
    
    bool CGuild::HasLand()
    {
    	return building::CManager::instance().FindLandByGuild(GetID()) != NULL;
    }
    
    // GUILD_JOIN_BUG_FIX
    /// ±ζµε ΓΚ΄λ event Α¤ΊΈ
    EVENTINFO(TInviteGuildEventInfo)
    {
    	DWORD	dwInviteePID;		///< ΓΚ΄λΉήΐΊ character ΐΗ PID
    	DWORD	dwGuildID;		///< ΓΚ΄λΗΡ Guild ΐΗ ID
    
    	TInviteGuildEventInfo()
    	: dwInviteePID( 0 )
    	, dwGuildID( 0 )
    	{
    	}
    };
    
    /**
     * ±ζµε ΓΚ΄λ event callback ΗΤΌφ.
     * event °΅ ΉίµΏΗΟΈι ΓΚ΄λ °Εΐύ·Ξ Γ³Έ®ΗΡ΄Ω.
     */
    EVENTFUNC( GuildInviteEvent )
    {
    	TInviteGuildEventInfo *pInfo = dynamic_cast<TInviteGuildEventInfo*>( event->info );
    
    	if ( pInfo == NULL )
    	{
    		sys_err( "GuildInviteEvent> <Factor> Null pointer" );
    		return 0;
    	}
    
    	CGuild* pGuild = CGuildManager::instance().FindGuild( pInfo->dwGuildID );
    
    	if ( pGuild ) 
    	{
    		sys_log( 0, "GuildInviteEvent %s", pGuild->GetName() );
    		pGuild->InviteDeny( pInfo->dwInviteePID );
    	}
    
    	return 0;
    }
    
    void CGuild::Invite( LPCHARACTER pchInviter, LPCHARACTER pchInvitee )
    {
    	if (quest::CQuestManager::instance().GetPCForce(pchInviter->GetPlayerID())->IsRunning() == true)
    	{
    	    pchInviter->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λΉζΐΜ ΓΚ΄λ ½ΕΓ»ΐ» Ήήΐ» Όφ Ύψ΄Β »σΕΒΐΤ΄Ο΄Ω."));
    	    return;
    	}
    
    	
    	if (quest::CQuestManager::instance().GetPCForce(pchInvitee->GetPlayerID())->IsRunning() == true)
    		return;
    
    	if ( pchInvitee->IsBlockMode( BLOCK_GUILD_INVITE ) ) 
    	{
    		pchInviter->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λΉζΐΜ ±ζµε ΓΚ΄λ °ΕΊΞ »σΕΒΐΤ΄Ο΄Ω.") );
    		return;
    	} 
    	else if ( !HasGradeAuth( GetMember( pchInviter->GetPlayerID() )->grade, GUILD_AUTH_ADD_MEMBER ) ) 
    	{
    		pchInviter->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ±ζµεΏψΐ» ΓΚ΄λΗ ±ΗΗΡΐΜ Ύψ½ΐ΄Ο΄Ω.") );
    		return;
    	} 
    	else if ( pchInvitee->GetEmpire() != pchInviter->GetEmpire() ) 
    	{
    		pchInviter->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΄ΩΈ¥ Α¦±Ή »η¶χΐ» ±ζµεΏ΅ ΓΚ΄λΗ Όφ Ύψ½ΐ΄Ο΄Ω.") );
    		return;
    	}
    
    	GuildJoinErrCode errcode = VerifyGuildJoinableCondition( pchInvitee );
    	switch ( errcode ) 
    	{
    		case GERR_NONE: break;
    		case GERR_WITHDRAWPENALTY:
    						pchInviter->ChatPacket( CHAT_TYPE_INFO, 
    								LC_TEXT("<±ζµε> Ε»ΕπΗΡ ΘΔ %dΐΟΐΜ Αφ³Αφ ΎΚΐΊ »η¶χΐΊ ±ζµεΏ΅ ΓΚ΄λΗ Όφ Ύψ½ΐ΄Ο΄Ω."), 
    								quest::CQuestManager::instance().GetEventFlag( "guild_withdraw_delay" ) );
    						return;
    		case GERR_COMMISSIONPENALTY:
    						pchInviter->ChatPacket( CHAT_TYPE_INFO, 
    								LC_TEXT("<±ζµε> ±ζµεΈ¦ ΗΨ»κΗΡ Αφ %dΐΟΐΜ Αφ³Αφ ΎΚΐΊ »η¶χΐΊ ±ζµεΏ΅ ΓΚ΄λΗ Όφ Ύψ½ΐ΄Ο΄Ω."), 
    								quest::CQuestManager::instance().GetEventFlag( "guild_disband_delay") );
    						return;
    		case GERR_ALREADYJOIN:	pchInviter->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λΉζΐΜ ΐΜΉΜ ΄ΩΈ¥ ±ζµεΏ΅ ΌΣΗΨΐΦ½ΐ΄Ο΄Ω.")); return;
    		case GERR_GUILDISFULL:	pchInviter->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΓΦ΄λ ±ζµεΏψ ΌφΈ¦ ΓΚ°ϊΗί½ΐ΄Ο΄Ω.")); return;
    		case GERR_GUILD_IS_IN_WAR : pchInviter->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Ηφΐη ±ζµε°΅ ΐόΐο Αί ΐΤ΄Ο΄Ω.") ); return;
    		case GERR_INVITE_LIMIT : pchInviter->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Ηφΐη ½Ε±Τ °΅ΐΤ Α¦ΗΡ »σΕΒ ΐΤ΄Ο΄Ω.") ); return;
    
    		default: sys_err( "ignore guild join error(%d)", errcode ); return;
    	}
    
    	if ( m_GuildInviteEventMap.end() != m_GuildInviteEventMap.find( pchInvitee->GetPlayerID() ) )
    		return;
    
    	//
    	// ΐΜΊ¥Ζ® »ύΌΊ
    	// 
    	TInviteGuildEventInfo* pInfo = AllocEventInfo<TInviteGuildEventInfo>();
    	pInfo->dwInviteePID = pchInvitee->GetPlayerID();
    	pInfo->dwGuildID = GetID();
    
    	m_GuildInviteEventMap.insert(EventMap::value_type(pchInvitee->GetPlayerID(), event_create(GuildInviteEvent, pInfo, PASSES_PER_SEC(10))));
    
    	//
    	// ΓΚ΄λ Ήή΄Β character Ώ΅°Τ ΓΚ΄λ ΖΠΕ¶ ΐόΌΫ
    	// 
    
    	DWORD gid = GetID();
    
    	TPacketGCGuild p;
    	p.header	= HEADER_GC_GUILD;
    	p.size	= sizeof(p) + sizeof(DWORD) + GUILD_NAME_MAX_LEN + 1;
    	p.subheader	= GUILD_SUBHEADER_GC_GUILD_INVITE;
    
    	TEMP_BUFFER buf;
    	buf.write( &p, sizeof(p) );
    	buf.write( &gid, sizeof(DWORD) );
    	buf.write( GetName(), GUILD_NAME_MAX_LEN + 1 );
    
    	pchInvitee->GetDesc()->Packet( buf.read_peek(), buf.size() );
    }
    
    void CGuild::InviteAccept( LPCHARACTER pchInvitee )
    {
    	EventMap::iterator itFind = m_GuildInviteEventMap.find( pchInvitee->GetPlayerID() );
    	if ( itFind == m_GuildInviteEventMap.end() ) 
    	{
    		sys_log( 0, "GuildInviteAccept from not invited character(invite guild: %s, invitee: %s)", GetName(), pchInvitee->GetName() );
    		return;
    	}
    
    	event_cancel( &itFind->second );
    	m_GuildInviteEventMap.erase( itFind );
    
    	GuildJoinErrCode errcode = VerifyGuildJoinableCondition( pchInvitee );
    	switch ( errcode ) 
    	{
    		case GERR_NONE: break;
    		case GERR_WITHDRAWPENALTY:
    						pchInvitee->ChatPacket( CHAT_TYPE_INFO, 
    								LC_TEXT("<±ζµε> Ε»ΕπΗΡ ΘΔ %dΐΟΐΜ Αφ³Αφ ΎΚΐΊ »η¶χΐΊ ±ζµεΏ΅ ΓΚ΄λΗ Όφ Ύψ½ΐ΄Ο΄Ω."), 
    								quest::CQuestManager::instance().GetEventFlag( "guild_withdraw_delay" ) );
    						return;
    		case GERR_COMMISSIONPENALTY:
    						pchInvitee->ChatPacket( CHAT_TYPE_INFO, 
    								LC_TEXT("<±ζµε> ±ζµεΈ¦ ΗΨ»κΗΡ Αφ %dΐΟΐΜ Αφ³Αφ ΎΚΐΊ »η¶χΐΊ ±ζµεΏ΅ ΓΚ΄λΗ Όφ Ύψ½ΐ΄Ο΄Ω."), 
    								quest::CQuestManager::instance().GetEventFlag( "guild_disband_delay") );
    						return;
    		case GERR_ALREADYJOIN:	pchInvitee->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> »σ΄λΉζΐΜ ΐΜΉΜ ΄ΩΈ¥ ±ζµεΏ΅ ΌΣΗΨΐΦ½ΐ΄Ο΄Ω.")); return;
    		case GERR_GUILDISFULL:	pchInvitee->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ζµε> ΓΦ΄λ ±ζµεΏψ ΌφΈ¦ ΓΚ°ϊΗί½ΐ΄Ο΄Ω.")); return;
    		case GERR_GUILD_IS_IN_WAR : pchInvitee->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Ηφΐη ±ζµε°΅ ΐόΐο Αί ΐΤ΄Ο΄Ω.") ); return;
    		case GERR_INVITE_LIMIT : pchInvitee->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<±ζµε> Ηφΐη ½Ε±Τ °΅ΐΤ Α¦ΗΡ »σΕΒ ΐΤ΄Ο΄Ω.") ); return;
    
    		default: sys_err( "ignore guild join error(%d)", errcode ); return;
    	}
    
    	RequestAddMember( pchInvitee, 15 );
    }
    
    void CGuild::InviteDeny( DWORD dwPID )
    {
    	EventMap::iterator itFind = m_GuildInviteEventMap.find( dwPID );
    	if ( itFind == m_GuildInviteEventMap.end() ) 
    	{
    		sys_log( 0, "GuildInviteDeny from not invited character(invite guild: %s, invitee PID: %d)", GetName(), dwPID );
    		return;
    	}
    
    	event_cancel( &itFind->second );
    	m_GuildInviteEventMap.erase( itFind );
    }
    
    CGuild::GuildJoinErrCode CGuild::VerifyGuildJoinableCondition( const LPCHARACTER pchInvitee )
    {
    	if ( get_global_time() - pchInvitee->GetQuestFlag( "guild_manage.new_withdraw_time" )
    			< CGuildManager::instance().GetWithdrawDelay() )
    		return GERR_WITHDRAWPENALTY;
    	else if ( get_global_time() - pchInvitee->GetQuestFlag( "guild_manage.new_disband_time" )
    			< CGuildManager::instance().GetDisbandDelay() )
    		return GERR_COMMISSIONPENALTY;
    	else if ( pchInvitee->GetGuild() )
    		return GERR_ALREADYJOIN;
    	else if ( GetMemberCount() >= GetMaxMemberCount() )
    	{
    		sys_log(1, "GuildName = %s, GetMemberCount() = %d, GetMaxMemberCount() = %d (32 + MAX(level(%d)-10, 0) * 2 + bonus(%d)", 
    				GetName(), GetMemberCount(), GetMaxMemberCount(), m_data.level, m_iMemberCountBonus);
    		return GERR_GUILDISFULL;
    	}
    	else if ( UnderAnyWar() != 0 )
    	{
    		return GERR_GUILD_IS_IN_WAR;
    	}
    	else if ( LC_IsBrazil() == true )
    	{
    		std::unique_ptr<SQLMsg> pMsg( DBManager::instance().DirectQuery("SELECT value FROM guild_invite_limit WHERE id=%d", GetID()) );
    
    		if ( pMsg->Get()->uiNumRows > 0 )
    		{
    			MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
    			time_t limit_time=0;
    			str_to_number( limit_time, row[0] );
    
    			if ( test_server == true )
    			{
    				limit_time += quest::CQuestManager::instance().GetEventFlag("guild_invite_limit") * 60;
    			}
    			else
    			{
    				limit_time += quest::CQuestManager::instance().GetEventFlag("guild_invite_limit") * 24 * 60 * 60;
    			}
    
    			if ( get_global_time() < limit_time ) return GERR_INVITE_LIMIT;
    		}
    	}
    
    	return GERR_NONE;
    }
    // END_OF_GUILD_JOIN_BUG_FIX
    
    bool CGuild::ChangeMasterTo(DWORD dwPID)
    {
    	if ( GetMember(dwPID) == NULL ) return false;
    
    	TPacketChangeGuildMaster p;
    	p.dwGuildID = GetID();
    	p.idFrom = GetMasterPID();
    	p.idTo = dwPID;
    
    	db_clientdesc->DBPacket(HEADER_GD_REQ_CHANGE_GUILD_MASTER, 0, &p, sizeof(p));
    
    	return true;
    }
    
    void CGuild::SendGuildDataUpdateToAllMember(SQLMsg* pmsg)
    {
    	TGuildMemberOnlineContainer::iterator iter = m_memberOnline.begin();
    
    	for (; iter != m_memberOnline.end(); iter++ )
    	{
    		SendGuildInfoPacket(*iter);
    		SendAllGradePacket(*iter);
    	}
    }

     

    I am using clang++-devel as the compiler and C++1z as std version.

    Makefile (look for "<===" to find line 90 - mentioned in the error output):

    Spoiler
    
    SVN_VERSION = 70140-BETA
    
    CC = clang++-devel
    
    INCDIR =
    LIBDIR =
    BINDIR = ..
    ROBJDIR = release
    DOBJDIR = debug
    SRV_DIR = /home/game
    $(shell if [ ! -d lib ]; then mkdir lib; fi)
    $(shell if [ ! -d $(DOBJDIR) ]; then mkdir $(DOBJDIR); fi)
    $(shell if [ ! -d $(ROBJDIR) ]; then mkdir $(ROBJDIR); fi)
    
    # Standard Setting
    LIBS = -pthread -lm -lmd -llua -llualib
    # Removed -fno-rtti 
    CFLAGS = -m32 -Wall -D_THREAD_SAFE -pipe -msse2 -mssse3 -stdlib=libc++ -std=c++1z -Wno-invalid-source-encoding -DCRYPTOPP_DISABLE_ASM
    
    #debug
    CFLAGS_DBG = $(CFLAGS)
    CLINKFLAGS_DBG = $(CFLAGS_DBG)
    CFLAGS_DBG += -g3 -O1 -ggdb -DNDEBUG -fexceptions
    #CLINKFLAGS_DBG += -fstandalone-debug -fsanitize=address
    
    #release
    CFLAGS_REL = $(CFLAGS)
    CLINKFLAGS_REL = $(CFLAGS_REL)
    CFLAGS_REL += -Ofast -g0 -fexceptions
    #CLINKFLAGS_REL += -flto
    
    # DevIL
    LIBS += -lIL -ljpeg
    
    LIBDIR += -L/usr/local/lib/mysql
    LIBS += -lmysqlclient -lz
    
    # Miscellaneous external libraries
    LIBS += -lcryptopp -lgtest
    
    # openssl
    INCDIR += -I/usr/include
    LIBS += -lssl
    LIBS += /usr/lib/libssl.a
    
    # Project Library
    INCDIR += -I../../liblua/include -I../../
    INCDIR += -I/usr/local/include
    LIBDIR += -L../../libthecore/lib -L../../libpoly/lib -L../../libsql/lib -L../../libgame/lib -L../../liblua/lib
    LIBDIR += -L/usr/local/lib
    LIBS += -lthecore -lpoly -lsql -lgame -llua -llzo2
    USE_STACKTRACE = 0
    ifeq ($(USE_STACKTRACE), 1)
    LIBS += /usr/local/lib/libexecinfo.a
    endif
    
    DTARGET  = $(BINDIR)/game_r$(SVN_VERSION)_debug
    RTARGET = $(BINDIR)/game_r$(SVN_VERSION)_release
    
    CPPFILES := $(wildcard *.cpp)
    OBJ_DBG_FILES := $(addprefix debug/,$(notdir $(CPPFILES:.cpp=.o)))
    OBJ_REL_FILES := $(addprefix release/,$(notdir $(CPPFILES:.cpp=.o)))
    
    DCPPOBJS	= $(CPPFILE:%.cpp=$(DOBJDIR)/%.o)
    RCPPOBJS	= $(CPPFILE:%.cpp=$(ROBJDIR)/%.o)
    
    default: $(DTARGET) $(RTARGET)
    
    debug: $(DTARGET)
    
    release: $(RTARGET)
    
    $(DOBJDIR)/%.o: %.cpp
    	@echo Compile $@
    	@$(CC) $(CFLAGS_DBG) $(INCDIR) -D__SVN_VERSION__=\"$(SVN_VERSION)\" -c $< -o $@
    $(ROBJDIR)/%.o: %.cpp
    	@echo Compile $@
    	@$(CC) $(CFLAGS_REL) $(INCDIR) -D__SVN_VERSION__=\"$(SVN_VERSION)\" -c $< -o $@
    
    limit_time:
    	@echo update limit time
    	@python update_limit_time.py
    
    $(DTARGET): $(OBJ_DBG_FILES)
    	@echo Linking...$(DTARGET)
    	@$(CC) $(CLINKFLAGS_DBG) $(LIBDIR) $(OBJ_DBG_FILES) $(LIBS) -o $(DTARGET)
    
    $(RTARGET): $(OBJ_REL_FILES)
    	@echo Linking...$(RTARGET)
    	@$(CC) $(CLINKFLAGS_REL) $(LIBDIR) $(OBJ_REL_FILES) $(LIBS) -o $(RTARGET) <==== THIS IS LINE 90 (MENTIONED IN THE ERROR OUTPUT)
    
    
    clean:
    	@rm -f debug/*
    	@rm -f release/*
    	@rm -f $(BINDIR)/game_r* $(BINDIR)/conv
    
    tag:
    	ctags *.cpp *.h *.c
    
    dep:
    	makedepend -f Depend $(INCDIR) -I/usr/local/include/c++/v1 -I/usr/include/c++/v1 -prelease/ $(CPPFILE) 2> /dev/null > Depend
    
    installd: $(DTARGET)
    	rm -rf $(SRV_DIR)/share/game
    	cp $(DTARGET) $(SRV_DIR)/share/game
    
    installr: $(RTARGET)
    	rm -rf $(SRV_DIR)/share/game
    	cp $(RTARGET) $(SRV_DIR)/share/game
    
    
    sinclude Depend

     

    I would appreciate any comment bringing me closer to understand to whatever goes on here.

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.