- Mesaj
- 78
- Beğeni
- 57
- Puan
- 331
- Ticaret Puanı
- 0
Makefile
tables.h
fake_player_manager.cpp
fake_player_manager.h
openai_client.cpp
openai_client.h
Makefile:
CC = g++
OBJDIR = obj
$(shell if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi)
CFLAGS = -g -Wall -O2 -m32 -pipe -fexceptions -D_THREAD_SAFE -DNDEBUG -mtune=i686 -fstack-protector-all
INCDIR = -I../../libdevil -I../../libmysql/7.x-5.1.35 -I../../../Extern/include/boost -I../../../Extern/include -I../../liblua/include -I/usr/local/include -L/usr/local/lib/mysql
LIBDIR = -L../../libdevil -L../../libmysql/7.x-5.1.35 -L../../../Extern/lib -L../../libthecore/lib -L../../libpoly -L../../libsql -L../../libgame/lib -L../../liblua/lib -L/usr/local/lib
LIBS = -pthread -lm -lmd -lIL -lpng -ltiff -lmng -llcms -ljpeg -lmysqlclient -L/usr/local/lib/mysql -lz -lcryptopp -lthecore -lpoly -llua -llualib -lsql -lgame
LIBS = -pthread -lm -lmd -lIL -lpng -ltiff -lmng -llcms -ljpeg -lmysqlclient -L/usr/local/lib/mysql -lz -lcryptopp -lthecore -lpoly -llua -llualib -lsql -lgame [B]-lcurl[/B]
TARGET = ../game
CFILE = minilzo.c
CPPFILE = BattleArena.cpp FSM.cpp MarkConvert.cpp MarkImage.cpp MarkManager.cpp OXEvent.cpp TrafficProfiler.cpp ani.cpp\
arena.cpp banword.cpp battle.cpp blend_item.cpp block_country.cpp buffer_manager.cpp building.cpp castle.cpp\
char.cpp char_affect.cpp char_battle.cpp char_change_empire.cpp char_horse.cpp char_item.cpp char_manager.cpp\
char_quickslot.cpp char_resist.cpp char_skill.cpp char_state.cpp PetSystem.cpp cmd.cpp cmd_emotion.cpp cmd_general.cpp\
cmd_gm.cpp cmd_oxevent.cpp config.cpp constants.cpp crc32.cpp cube.cpp db.cpp desc.cpp\
desc_client.cpp desc_manager.cpp desc_p2p.cpp dungeon.cpp entity.cpp\
entity_view.cpp event.cpp event_queue.cpp exchange.cpp file_loader.cpp fishing.cpp gm.cpp guild.cpp\
guild_manager.cpp guild_war.cpp horse_rider.cpp horsename_manager.cpp input.cpp input_auth.cpp input_db.cpp\
input_login.cpp input_main.cpp input_p2p.cpp input_udp.cpp\
item.cpp item_addon.cpp item_attribute.cpp item_manager.cpp item_manager_idrange.cpp\
locale_service.cpp log.cpp login_data.cpp lzo_manager.cpp marriage.cpp\
messenger_manager.cpp mining.cpp mob_manager.cpp motion.cpp over9refine.cpp p2p.cpp packet_info.cpp\
party.cpp polymorph.cpp priv_manager.cpp pvp.cpp\
questevent.cpp questlua.cpp questlua_affect.cpp questlua_arena.cpp questlua_ba.cpp questlua_building.cpp\
questlua_danceevent.cpp questlua_dungeon.cpp questlua_forked.cpp questlua_game.cpp questlua_global.cpp\
questlua_guild.cpp questlua_horse.cpp questlua_pet.cpp questlua_item.cpp questlua_marriage.cpp\
questlua_npc.cpp questlua_oxevent.cpp questlua_party.cpp questlua_pc.cpp\
questlua_quest.cpp questlua_target.cpp questmanager.cpp questnpc.cpp questpc.cpp\
refine.cpp regen.cpp safebox.cpp sectree.cpp sectree_manager.cpp sequence.cpp shop.cpp\
skill.cpp start_position.cpp target.cpp text_file_loader.cpp trigger.cpp utils.cpp vector.cpp war_map.cpp\
wedding.cpp xmas_event.cpp version.cpp threeway_war.cpp map_location.cpp\
BlueDragon.cpp BlueDragon_Binder.cpp DragonLair.cpp questlua_dragonlair.cpp\
skill_power.cpp affect.cpp\
FileMonitor_FreeBSD.cpp ClientPackageCryptInfo.cpp cipher.cpp\
buff_on_attributes.cpp\
group_text_parse_tree.cpp\
shop_manager.cpp shopEx.cpp item_manager_read_tables.cpp
group_text_parse_tree.cpp\
shop_manager.cpp shopEx.cpp item_manager_read_tables.cpp [B]openai_client.cpp fake_player_manager.cpp[/B]
COBJS = $(CFILE:%.c=$(OBJDIR)/%.o)
CPPOBJS = $(CPPFILE:%.cpp=$(OBJDIR)/%.o)
MAINOBJ = $(OBJDIR)/main.o
MAINCPP = main.cpp
default: $(TARGET)
$(OBJDIR)/minilzo.o: minilzo.c
@$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
@echo compile $<
$(OBJDIR)/version.o: version.cpp
@$(CC) $(CFLAGS) -D__P4_VERSION__=\"metin2\" -c $< -o $@
@echo compile $<
$(OBJDIR)/%.o: %.cpp
@echo compile $<
@$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
limit_time:
@echo update limit time
@python update_limit_time.py
tables.h
C++:
typedef struct SPacketGDFakePlayer
{
BYTE bSubheader;
} TPacketGDFakePlayer;
typedef struct SFakePlayerLoginData
{
char szName[CHARACTER_NAME_MAX_LEN + 1];
long lMapIndex;
long lX;
long lY;
int iRotation;
} TFakePlayerLoginData;
typedef struct SFakePlayerLogoutData
{
char szName[CHARACTER_NAME_MAX_LEN + 1];
} TFakePlayerLogoutData;
enum EFakePlayerGDSubheaders
{
FAKE_PLAYER_SUBHEADER_GD_LOGIN,
FAKE_PLAYER_SUBHEADER_GD_LOGOUT,
};
enum EFakePlayerDGSubheaders
{
FAKE_PLAYER_SUBHEADER_DG_LOGIN,
FAKE_PLAYER_SUBHEADER_DG_LOGOUT,
};
fake_player_manager.cpp
C++:
#include "stdafx.h"
#ifdef __JACK_WRESTLER_FAKE_PLAYER__
#include "fake_player_manager.h"
#include "char_manager.h"
#include "sectree_manager.h"
#include "item_manager.h"
#include "desc_manager.h"
#include "buffer_manager.h"
#include "db.h"
#include <boost/lexical_cast.hpp>
CFakePlayer::CFakePlayer(TFakePlayerLoginData* fakePlayerLoginData)
{
Login(fakePlayerLoginData);
}
CFakePlayer::~CFakePlayer()
{
if (m_pFakePlayer)
M2_DESTROY_CHARACTER(m_pFakePlayer);
}
void CFakePlayer::Login(TFakePlayerLoginData* fakePlayerLoginData)
{
long lMapIndex = fakePlayerLoginData->lMapIndex;
long lX = fakePlayerLoginData->lX;
long lY = fakePlayerLoginData->lY;
if (LPSECTREE sectree = SECTREE_MANAGER::instance().Get(lMapIndex, lX, lY); !sectree)
{
CFakePlayerManager::instance().FakePlayerLogout(fakePlayerLoginData->szName);
return;
}
LPCHARACTER pFakePlayer = CHARACTER_MANAGER::instance().CreateCharacter("Reinhardt");
if (!pFakePlayer)
{
CFakePlayerManager::instance().FakePlayerLogout(fakePlayerLoginData->szName);
return;
}
pFakePlayer->SetCharType(CHAR_TYPE_PC);
pFakePlayer->SetRotation(fakePlayerLoginData->iRotation);
pFakePlayer->SetXYZ(lX, lY, 0);
pFakePlayer->SetMapIndex(lMapIndex);
pFakePlayer->SetName(fakePlayerLoginData->szName);
pFakePlayer->SetFakePlayer(true);
m_pFakePlayer = pFakePlayer;
if (!LoadFakePlayer())
{
sys_err("<FakePlayer> cant Load FakePlayer %s.", fakePlayerLoginData->szName);
CFakePlayerManager::instance().FakePlayerLogout(fakePlayerLoginData->szName);
return;
}
if (!pFakePlayer->Show(lMapIndex, lX, lY, 0))
{
CFakePlayerManager::instance().FakePlayerLogout(fakePlayerLoginData->szName);
return;
}
#ifdef WJ_EXTENDED_PET_SYSTEM
pFakePlayer->CheckPet();
#endif
pFakePlayer->CheckMount();
pFakePlayer->ReviveInvisible(5);
const char* apiKey = getenv("OPENAI_API_KEY");
if (apiKey && *apiKey)
{
std::string prompt = std::string("Say hello to players, I am ") + m_pFakePlayer->GetName();
Speak(prompt);
}
}
void CFakePlayer::Speak(const std::string& prompt)
{
const char* apiKey = getenv("OPENAI_API_KEY");
if (!apiKey || !*apiKey)
return;
OpenAIClient client(apiKey);
std::string text = client.Complete(prompt);
if (!text.empty() && m_pFakePlayer)
m_pFakePlayer->ChatPacket(CHAT_TYPE_TALKING, "%s", text.c_str());
}
bool CFakePlayer::LoadFakePlayer()
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery),
"SELECT race+0, level, empire+0, st, ht, dx, iq, alignment, block_eq, guild_id, copy_eq_of, language FROM fake_player WHERE name = '%s'",
m_pFakePlayer->GetName());
std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szQuery));
if (!pMsg->Get()->uiNumRows)
return false;
size_t col = 0;
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
std::string stCopyName = "";
m_pFakePlayer->SetRace(boost::lexical_cast<uint32_t>(row[col++]) - 1);
m_pFakePlayer->SetLevel(boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetEmpire(boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetPoint(POINT_ST, boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetPoint(POINT_HT, boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetPoint(POINT_DX, boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetPoint(POINT_IQ, boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->UpdateAlignment(boost::lexical_cast<uint32_t>(row[col++]) * 10);
m_pFakePlayer->SetFakePlayerBlockEQ(boost::lexical_cast<uint32_t>(row[col++]));
m_pFakePlayer->SetFakePlayerGuildID(boost::lexical_cast<uint32_t>(row[col++]));
stCopyName = row[col++];
m_pFakePlayer->SetLanguage(row[col++]);
m_pFakePlayer->SetPoint(POINT_MOV_SPEED, EFakePlayer::FAKE_PLAYER_MOV_SPEED);
m_pFakePlayer->ComputePoints();
m_pFakePlayer->PointChange(POINT_HP, m_pFakePlayer->GetMaxHP() - m_pFakePlayer->GetHP());
m_pFakePlayer->StartRecoveryEvent();
m_pFakePlayer->FakePlayerCreatePetSystem();
if (stCopyName.empty())
LoadFakePlayerItem(m_pFakePlayer->GetName());
else
LoadFakePlayerItem(stCopyName.c_str());
return true;
}
void CFakePlayer::LoadFakePlayerItem(const char* szName)
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery),
"SELECT wear_pos+0, vnum, socket0, socket1, socket2, socket3, socket4, socket5,"
" attrtype0, attrvalue0,"
" attrtype1, attrvalue1,"
" attrtype2, attrvalue2,"
" attrtype3, attrvalue3,"
" attrtype4, attrvalue4,"
" attrtype5, attrvalue5,"
" attrtype6, attrvalue6"
" FROM fake_player_item WHERE name = '%s'",
szName);
std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szQuery));
if (!pMsg->Get()->uiNumRows)
return;
MYSQL_ROW row;
size_t col = 0;
TFakePlayerItemData itemData;
for (size_t i = 0; i < mysql_num_rows(pMsg->Get()->pSQLResult); ++i)
{
col = 0;
memset(&itemData, 0, sizeof(itemData));
row = mysql_fetch_row(pMsg->Get()->pSQLResult);
itemData.bWearPos = boost::lexical_cast<uint32_t>(row[col++]) - 1;
itemData.dwVnum = boost::lexical_cast<uint32_t>(row[col++]);
for (size_t j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
itemData.alSockets[j] = boost::lexical_cast<uint32_t>(row[col++]);
for (size_t j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; ++j)
{
itemData.aAttr[j].bType = boost::lexical_cast<uint32_t>(row[col++]);
itemData.aAttr[j].sValue = boost::lexical_cast<uint32_t>(row[col++]);
}
LPITEM item = ITEM_MANAGER::instance().CreateItem(itemData.dwVnum);
if (!item)
{
sys_err("<FakePlayer> cannot create item by vnum %u (name %s)", itemData.dwVnum, szName);
continue;
}
item->SetSkipSave(true);
item->SetSockets(itemData.alSockets);
item->SetAttributes(itemData.aAttr);
if (item->CheckItemUseLevel(m_pFakePlayer->GetLevel()) &&
item->EquipTo(m_pFakePlayer, itemData.bWearPos))
item->StopExpireEvents();
else
M2_DELETE(item);
}
}
void CFakePlayerManager::Initialize()
{
m_mapFakePlayer.clear();
}
void CFakePlayerManager::Destroy()
{
Initialize();
}
void CFakePlayerManager::DGFakePlayer(uint32_t dwHandle, const char* c_pData)
{
TPacketDGFakePlayer* p = (TPacketDGFakePlayer*)c_pData;
c_pData += sizeof(TPacketDGFakePlayer);
switch (p->bSubheader)
{
case FAKE_PLAYER_SUBHEADER_DG_LOGIN:
SpawnFakePlayer((TFakePlayerLoginData*)c_pData);
return;
case FAKE_PLAYER_SUBHEADER_DG_LOGOUT:
DestroyFakePlayer((TFakePlayerLogoutData*)c_pData);
return;
default:
sys_err("CFakePlayerManager::DGFakePlayer: Unknown subheader %d", p->bSubheader);
break;
}
}
void CFakePlayerManager::FakePlayerLogin(LPCHARACTER ch, TFakePlayerLoginData* fakePlayerLoginData)
{
TPacketGDFakePlayer packet;
packet.bSubheader = FAKE_PLAYER_SUBHEADER_GD_LOGIN;
TEMP_BUFFER buf;
buf.write(&packet, sizeof(packet));
buf.write(fakePlayerLoginData, sizeof(TFakePlayerLoginData));
db_clientdesc->DBPacket(HEADER_GD_FAKE_PLAYER, ch->GetDesc()->GetHandle(), buf.read_peek(), buf.size());
}
void CFakePlayerManager::FakePlayerLogout(const char* szName, LPCHARACTER ch)
{
TPacketGDFakePlayer packet;
packet.bSubheader = FAKE_PLAYER_SUBHEADER_GD_LOGOUT;
TFakePlayerLogoutData fakePlayerLogoutData;
strlcpy(fakePlayerLogoutData.szName, szName, sizeof(fakePlayerLogoutData.szName));
TEMP_BUFFER buf;
buf.write(&packet, sizeof(packet));
buf.write(&fakePlayerLogoutData, sizeof(fakePlayerLogoutData));
if (ch)
db_clientdesc->DBPacket(HEADER_GD_FAKE_PLAYER, ch->GetDesc()->GetHandle(), buf.read_peek(), buf.size());
else
db_clientdesc->DBPacket(HEADER_GD_FAKE_PLAYER, 0, buf.read_peek(), buf.size());
}
void CFakePlayerManager::SpawnFakePlayer(TFakePlayerLoginData* fakePlayerLoginData)
{
std::unique_ptr<CFakePlayer> pFakePlayer = std::make_unique<CFakePlayer>(fakePlayerLoginData);
m_mapFakePlayer.insert(TFakePlayerMap::value_type(fakePlayerLoginData->szName, std::move(pFakePlayer)));
}
void CFakePlayerManager::DestroyFakePlayer(TFakePlayerLogoutData* fakePlayerLogoutData)
{
auto it = m_mapFakePlayer.find(fakePlayerLogoutData->szName);
if (it == m_mapFakePlayer.end())
return;
m_mapFakePlayer.erase(it);
}
LPCHARACTER CFakePlayerManager::FindFakePlayer(std::string stName)
{
auto it = m_mapFakePlayer.find(stName);
if (it == m_mapFakePlayer.end())
return nullptr;
return it->second->GetFakePlayer();
}
#endif // __JACK_WRESTLER_FAKE_PLAYER__
fake_player_manager.h
C++:
#ifndef FAKE_PLAYER_MANAGER_H
#define FAKE_PLAYER_MANAGER_H
#include <memory>
#include <map>
#include <string>
#include "openai_client.h"
#include "char.h"
#include "singleton.h"
#include "../../common/tables.h"
#ifdef __JACK_WRESTLER_FAKE_PLAYER__
class CFakePlayer
{
public:
explicit CFakePlayer(TFakePlayerLoginData* fakePlayerLoginData);
~CFakePlayer();
void Login(TFakePlayerLoginData* fakePlayerLoginData);
bool LoadFakePlayer();
void LoadFakePlayerItem(const char* szName);
void Speak(const std::string& prompt);
LPCHARACTER GetFakePlayer() { return m_pFakePlayer; }
private:
LPCHARACTER m_pFakePlayer;
};
class CFakePlayerManager : public singleton<CFakePlayerManager>
{
typedef std::map<std::string, std::unique_ptr<CFakePlayer>> TFakePlayerMap;
public:
void Initialize();
void Destroy();
void DGFakePlayer(uint32_t dwHandle, const char* c_pData);
void FakePlayerLogin(LPCHARACTER ch, TFakePlayerLoginData* fakePlayerLoginData);
void FakePlayerLogout(const char* szName, LPCHARACTER ch = nullptr);
void SpawnFakePlayer(TFakePlayerLoginData* fakePlayerLoginData);
void DestroyFakePlayer(TFakePlayerLogoutData* fakePlayerLogoutData);
LPCHARACTER FindFakePlayer(std::string stName);
private:
TFakePlayerMap m_mapFakePlayer;
};
#endif // __JACK_WRESTLER_FAKE_PLAYER__
#endif // FAKE_PLAYER_MANAGER_H
openai_client.cpp
C++:
#include "stdafx.h"
#include "openai_client.h"
#include <curl/curl.h>
#include <sstream>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
size_t total = size * nmemb;
std::string* s = static_cast<std::string*>(userp);
s->append(static_cast<char*>(contents), total);
return total;
}
static std::string Escape(const std::string& in)
{
std::string out;
for (char c : in) {
switch (c) {
case '\\': out += "\\\\"; break;
case '"': out += "\\\""; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
default: out += c; break;
}
}
return out;
}
static std::string ExtractText(const std::string& json)
{
size_t pos = json.find("\"text\"");
if (pos == std::string::npos) return std::string();
pos = json.find('"', json.find(':', pos));
if (pos == std::string::npos) return std::string();
size_t end = json.find('"', pos + 1);
if (end == std::string::npos) return std::string();
return json.substr(pos + 1, end - pos - 1);
}
OpenAIClient::OpenAIClient(const std::string& api_key)
: api_key_(api_key)
{
}
std::string OpenAIClient::Complete(const std::string& prompt)
{
if (api_key_.empty())
return std::string();
CURL* curl = curl_easy_init();
if (!curl)
return std::string();
std::string readBuffer;
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
std::string auth = "Authorization: Bearer " + api_key_;
headers = curl_slist_append(headers, auth.c_str());
std::ostringstream oss;
oss << "{\"model\":\"text-davinci-003\",\"prompt\":\"" << Escape(prompt) << "\",\"max_tokens\":20}";
std::string data = oss.str();
curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/completions");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
if (res != CURLE_OK)
return std::string();
return ExtractText(readBuffer);
}
openai_client.h
C++:
#ifndef OPENAI_CLIENT_H
#define OPENAI_CLIENT_H
#include <string>
class OpenAIClient {
public:
explicit OpenAIClient(const std::string& api_key);
std::string Complete(const std::string& prompt);
private:
std::string api_key_;
};
#endif // OPENAI_CLIENT_H