Active Member Mind Rapist 188 Posted December 13, 2018 Active Member Share Posted December 13, 2018 When the compiler gets to the game link point, it throws this error: Spoiler 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&)' release/cipher.o: In function `DH2KeyAgreement::Prepare(void*, unsigned int*)': cipher.cpp:(.text+0xbe2): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text+0xc9a): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text+0xcd3): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text+0xd0c): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text+0xea7): undefined reference to `CryptoPP::AlignedDeallocate(void*)' release/cipher.o:cipher.cpp:(.text+0xf76): more undefined references to `CryptoPP::AlignedDeallocate(void*)' follow release/cipher.o: In function `CryptoPP::MontgomeryRepresentation::MontgomeryRepresentation(CryptoPP::MontgomeryRepresentation const&)': cipher.cpp:(.text._ZN8CryptoPP24MontgomeryRepresentationC2ERKS0_[_ZN8CryptoPP24MontgomeryRepresentationC2ERKS0_]+0x4e): undefined reference to `CryptoPP::AlignedAllocate(unsigned int)' cipher.cpp:(.text._ZN8CryptoPP24MontgomeryRepresentationC2ERKS0_[_ZN8CryptoPP24MontgomeryRepresentationC2ERKS0_]+0xc3): undefined reference to `CryptoPP::AlignedDeallocate(void*)' release/cipher.o: In function `CryptoPP::ModularArithmetic::ModularArithmetic(CryptoPP::ModularArithmetic const&)': cipher.cpp:(.text._ZN8CryptoPP17ModularArithmeticC2ERKS0_[_ZN8CryptoPP17ModularArithmeticC2ERKS0_]+0x83): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text._ZN8CryptoPP17ModularArithmeticC2ERKS0_[_ZN8CryptoPP17ModularArithmeticC2ERKS0_]+0xc3): undefined reference to `CryptoPP::AlignedDeallocate(void*)' release/cipher.o: In function `CryptoPP::ModularArithmetic::~ModularArithmetic()': cipher.cpp:(.text._ZN8CryptoPP17ModularArithmeticD2Ev[_ZN8CryptoPP17ModularArithmeticD2Ev]+0x32): undefined reference to `CryptoPP::AlignedDeallocate(void*)' cipher.cpp:(.text._ZN8CryptoPP17ModularArithmeticD2Ev[_ZN8CryptoPP17ModularArithmeticD2Ev]+0x67): undefined reference to `CryptoPP::AlignedDeallocate(void*)' release/cipher.o:cipher.cpp:(.text._ZN8CryptoPP17ModularArithmeticD2Ev[_ZN8CryptoPP17ModularArithmeticD2Ev]+0x9c): more undefined references to `CryptoPP::AlignedDeallocate(void*)' follow 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: 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); } } cipher.cpp: Spoiler #include "stdafx.h" #include "cipher.h" #ifdef _IMPROVED_PACKET_ENCRYPTION_ #include <cryptopp/modes.h> #include <cryptopp/nbtheory.h> #include <cryptopp/osrng.h> // Diffie-Hellman key agreement #include <cryptopp/dh.h> #include <cryptopp/dh2.h> // AES winner and candidates //#include <cryptopp/aes.h> #include <cryptopp/cast.h> #include <cryptopp/rc6.h> #include <cryptopp/mars.h> #include <cryptopp/serpent.h> #include <cryptopp/twofish.h> // Other block ciphers #include <cryptopp/blowfish.h> #include <cryptopp/camellia.h> #include <cryptopp/des.h> #include <cryptopp/idea.h> #include <cryptopp/rc5.h> #include <cryptopp/seed.h> #include <cryptopp/shacal2.h> #include <cryptopp/skipjack.h> #include <cryptopp/tea.h> #include <cryptopp/cryptoppLibLink.h> using namespace CryptoPP; // Block cipher algorithm selector abstract base class. struct BlockCipherAlgorithm { enum { kDefault, // to give more chances to default algorithm // AES winner and candidates // kAES, // Rijndael kRC6, kMARS, kTwofish, kSerpent, kCAST256, // Other block ciphers kIDEA, k3DES, // DES-EDE2 kCamellia, kSEED, kRC5, kBlowfish, kTEA, // kSKIPJACK, kSHACAL2, // End sentinel kMaxAlgorithms }; BlockCipherAlgorithm() {} virtual ~BlockCipherAlgorithm() {} static BlockCipherAlgorithm* Pick(int hint); virtual int GetBlockSize() const = 0; virtual int GetDefaultKeyLength() const = 0; virtual int GetIVLength() const = 0; virtual SymmetricCipher* CreateEncoder(const byte* key, size_t keylen, const byte* iv) const = 0; virtual SymmetricCipher* CreateDecoder(const byte* key, size_t keylen, const byte* iv) const = 0; }; // Block cipher (with CTR mode) algorithm selector template class. template<class T> struct BlockCipherDetail : public BlockCipherAlgorithm { BlockCipherDetail() {} virtual ~BlockCipherDetail() {} virtual int GetBlockSize() const { return T::BLOCKSIZE; } virtual int GetDefaultKeyLength() const { return T::DEFAULT_KEYLENGTH; } virtual int GetIVLength() const { return T::IV_LENGTH; } virtual SymmetricCipher* CreateEncoder(const byte* key, size_t keylen, const byte* iv) const { return new typename CTR_Mode<T>::Encryption(key, keylen, iv); } virtual SymmetricCipher* CreateDecoder(const byte* key, size_t keylen, const byte* iv) const { return new typename CTR_Mode<T>::Decryption(key, keylen, iv); } }; // Key agreement scheme abstract class. class KeyAgreement { public: KeyAgreement() {} virtual ~KeyAgreement() {} virtual size_t Prepare(void* buffer, size_t* length) = 0; virtual bool Agree(size_t agreed_length, const void* buffer, size_t length) = 0; const SecByteBlock& shared() const { return shared_; } protected: SecByteBlock shared_; }; // Crypto++ Unified Diffie-Hellman key agreement scheme implementation. class DH2KeyAgreement : public KeyAgreement { public: DH2KeyAgreement(); virtual ~DH2KeyAgreement(); virtual size_t Prepare(void* buffer, size_t* length); virtual bool Agree(size_t agreed_length, const void* buffer, size_t length); private: DH dh_; DH2 dh2_; SecByteBlock spriv_key_; SecByteBlock epriv_key_; }; Cipher::Cipher() : activated_(false), encoder_(NULL), decoder_(NULL), key_agreement_(NULL) { } Cipher::~Cipher() { if (activated_) { CleanUp(); } } void Cipher::CleanUp() { if (encoder_ != NULL) { delete encoder_; encoder_ = NULL; } if (decoder_ != NULL) { delete decoder_; decoder_ = NULL; } if (key_agreement_ != NULL) { delete key_agreement_; key_agreement_ = NULL; } activated_ = false; } size_t Cipher::Prepare(void* buffer, size_t* length) { assert(key_agreement_ == NULL); key_agreement_ = new DH2KeyAgreement(); assert(key_agreement_ != NULL); size_t agreed_length = key_agreement_->Prepare(buffer, length); if (agreed_length == 0) { delete key_agreement_; key_agreement_ = NULL; } return agreed_length; } bool Cipher::Activate(bool polarity, size_t agreed_length, const void* buffer, size_t length) { assert(activated_ == false); assert(key_agreement_ != NULL); if (activated_ != false) return false; if (key_agreement_->Agree(agreed_length, buffer, length)) { activated_ = SetUp(polarity); } delete key_agreement_; key_agreement_ = NULL; return activated_; } bool Cipher::SetUp(bool polarity) { assert(key_agreement_ != NULL); const SecByteBlock& shared = key_agreement_->shared(); // Pick a block cipher algorithm if (shared.size() < 2) { return false; } int hint_0 = shared.BytePtr()[*(shared.BytePtr()) % shared.size()]; int hint_1 = shared.BytePtr()[*(shared.BytePtr() + 1) % shared.size()]; BlockCipherAlgorithm* detail_0 = BlockCipherAlgorithm::Pick(hint_0); BlockCipherAlgorithm* detail_1 = BlockCipherAlgorithm::Pick(hint_1); assert(detail_0 != NULL); assert(detail_1 != NULL); std::unique_ptr<BlockCipherAlgorithm> algorithm_0(detail_0); std::unique_ptr<BlockCipherAlgorithm> algorithm_1(detail_1); const size_t key_length_0 = algorithm_0->GetDefaultKeyLength(); const size_t iv_length_0 = algorithm_0->GetBlockSize(); if (shared.size() < key_length_0 || shared.size() < iv_length_0) { return false; } const size_t key_length_1 = algorithm_1->GetDefaultKeyLength(); const size_t iv_length_1 = algorithm_1->GetBlockSize(); if (shared.size() < key_length_1 || shared.size() < iv_length_1) { return false; } // Pick encryption keys and initial vectors SecByteBlock key_0(key_length_0), iv_0(iv_length_0); SecByteBlock key_1(key_length_1), iv_1(iv_length_1); size_t offset; key_0.Assign(shared, key_length_0); offset = key_length_0; offset = std::min(key_length_0, shared.size() - key_length_1); key_1.Assign(shared.BytePtr() + offset, key_length_1); offset = shared.size() - iv_length_0; iv_0.Assign(shared.BytePtr() + offset, iv_length_0); offset = (offset < iv_length_1 ? 0 : offset - iv_length_1); iv_1.Assign(shared.BytePtr() + offset, iv_length_1); // Create encryption/decryption objects if (polarity) { encoder_ = algorithm_1->CreateEncoder(key_1, key_1.size(), iv_1); decoder_ = algorithm_0->CreateDecoder(key_0, key_0.size(), iv_0); } else { encoder_ = algorithm_0->CreateEncoder(key_0, key_0.size(), iv_0); decoder_ = algorithm_1->CreateDecoder(key_1, key_1.size(), iv_1); } assert(encoder_ != NULL); assert(decoder_ != NULL); return true; } BlockCipherAlgorithm* BlockCipherAlgorithm::Pick(int hint) { BlockCipherAlgorithm* detail; int selector = hint % kMaxAlgorithms; switch (selector) { // case kAES: // detail = new BlockCipherDetail<AES>(); break; case kRC6: detail = new BlockCipherDetail<RC6>(); break; case kMARS: detail = new BlockCipherDetail<MARS>(); break; case kTwofish: detail = new BlockCipherDetail<Twofish>(); break; case kSerpent: detail = new BlockCipherDetail<Serpent>(); break; case kCAST256: detail = new BlockCipherDetail<CAST256>(); break; case kIDEA: detail = new BlockCipherDetail<IDEA>(); break; case k3DES: detail = new BlockCipherDetail<DES_EDE2>(); break; case kCamellia: detail = new BlockCipherDetail<Camellia>(); break; case kSEED: detail = new BlockCipherDetail<SEED>(); break; case kRC5: detail = new BlockCipherDetail<RC5>(); break; case kBlowfish: detail = new BlockCipherDetail<Blowfish>(); break; case kTEA: detail = new BlockCipherDetail<TEA>(); break; // case kSKIPJACK: // detail = new BlockCipherDetail<SKIPJACK>(); // break; case kSHACAL2: detail = new BlockCipherDetail<SHACAL2>(); break; case kDefault: default: detail = new BlockCipherDetail<Twofish>(); // default algorithm break; } return detail; } DH2KeyAgreement::DH2KeyAgreement() : dh_(), dh2_(dh_) { } DH2KeyAgreement::~DH2KeyAgreement() { } size_t DH2KeyAgreement::Prepare(void* buffer, size_t* length) { // RFC 5114, 1024-bit MODP Group with 160-bit Prime Order Subgroup // http://tools.ietf.org/html/rfc5114#section-2.1 Integer p("0xB10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" "DF1FB2BC2E4A4371"); Integer g("0xA4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" "855E6EEB22B3B2E5"); Integer q("0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353"); // Schnorr Group primes are of the form p = rq + 1, p and q prime. They // provide a subgroup order. In the case of 1024-bit MODP Group, the // security level is 80 bits (based on the 160-bit prime order subgroup). // For a compare/contrast of using the maximum security level, see // dh-unified.zip. Also see http://www.cryptopp.com/wiki/Diffie-Hellman // and http://www.cryptopp.com/wiki/Security_level . AutoSeededRandomPool rnd; dh_.AccessGroupParameters().Initialize(p, q, g); if(!dh_.GetGroupParameters().ValidateGroup(rnd, 3)) { // Failed to validate prime and generator return 0; } p = dh_.GetGroupParameters().GetModulus(); q = dh_.GetGroupParameters().GetSubgroupOrder(); g = dh_.GetGroupParameters().GetGenerator(); // http://groups.google.com/group/sci.crypt/browse_thread/thread/7dc7eeb04a09f0ce Integer v = ModularExponentiation(g, q, p); if(v != Integer::One()) { // Failed to verify order of the subgroup return 0; } ////////////////////////////////////////////////////////////// spriv_key_.New(dh2_.StaticPrivateKeyLength()); epriv_key_.New(dh2_.EphemeralPrivateKeyLength()); SecByteBlock spub_key(dh2_.StaticPublicKeyLength()); SecByteBlock epub_key(dh2_.EphemeralPublicKeyLength()); dh2_.GenerateStaticKeyPair(rnd, spriv_key_, spub_key); dh2_.GenerateEphemeralKeyPair(rnd, epriv_key_, epub_key); // Prepare key agreement data const size_t spub_key_length = spub_key.size(); const size_t epub_key_length = epub_key.size(); const size_t data_length = spub_key_length + epub_key_length; if (*length < data_length) { // Not enough data buffer length return 0; } *length = data_length; byte* buf = (byte*)buffer; memcpy(buf, spub_key.BytePtr(), spub_key_length); memcpy(buf + spub_key_length, epub_key.BytePtr(), epub_key_length); return dh2_.AgreedValueLength(); } bool DH2KeyAgreement::Agree(size_t agreed_length, const void* buffer, size_t length) { if (agreed_length != dh2_.AgreedValueLength()) { // Shared secret size mismatch return false; } const size_t spub_key_length = dh2_.StaticPublicKeyLength(); const size_t epub_key_length = dh2_.EphemeralPublicKeyLength(); if (length != (spub_key_length + epub_key_length)) { // Wrong data length return false; } shared_.New(dh2_.AgreedValueLength()); const byte* buf = (const byte*)buffer; if (!dh2_.Agree(shared_, spriv_key_, epriv_key_, buf, buf + spub_key_length)) { // Failed to reach shared secret return false; } return true; } #endif // _IMPROVED_PACKET_ENCRYPTION_ // EOF cipher.cpp Compiler: c++-devel Crypto++ version: 7 Link to comment Share on other sites More sharing options...
ridetpro 116 Posted December 13, 2018 Share Posted December 13, 2018 Compile cryptopp with c++17 too and with c++devel Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted December 13, 2018 Author Active Member Share Posted December 13, 2018 I did it. Crypto++ 700 compiles only in C++17. I tried again: cryptopp700# gmake clean cryptopp700# gmake 'CXXFLAGS+=-std=c++1z' cryptopp700# strip --strip-all libcryptopp.a cryptopp700# mv libcryptopp.a /usr/local/lib game/src# gmake clean game/src# gmake release Results were the same... Link to comment Share on other sites More sharing options...
ridetpro 116 Posted December 13, 2018 Share Posted December 13, 2018 Acum 3 ore, Mind Rapist a spus: I did it. Crypto++ 700 compiles only in C++17. I tried again: cryptopp700# gmake clean cryptopp700# gmake 'CXXFLAGS+=-std=c++1z' cryptopp700# strip --strip-all libcryptopp.a cryptopp700# mv libcryptopp.a /usr/local/lib game/src# gmake clean game/src# gmake release Results were the same... Then you probably did not put the cryptopp7 headers in extern. Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted December 14, 2018 Author Active Member Share Posted December 14, 2018 8 hours ago, ridetpro said: Then you probably did not put the cryptopp7 headers in extern. The source has no extern it depends on system libs and includes. It hits in 2 files guild.cpp and cipher.cpp and I've been looking at their functions but couldn't find what's wrong. If there was only a way to know what lines it's talking about I could investigate more but all it says is guild.cpp:(.text+0x3939) UPDATE::: By adding a CFLAG called -DCRYPTOPP_DISABLE_ASM all the errors from file cipher.cpp have dissapeard! Errors for file guild.cpp remain tho... Link to comment Share on other sites More sharing options...
Bot Metin2 Dev 4882 Posted March 6, 2019 Bot Share Posted March 6, 2019 thx Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now