Changed quests/templates to quests/global. Changed default location for plugins to quests/plugins instead of quests. Added a single interpreter for lua instead of multiple ones.

This commit is contained in:
KimLS 2013-05-15 13:00:46 -07:00
parent 3cc1065873
commit 2336aa0e4f
6 changed files with 151 additions and 125 deletions

View File

@ -167,7 +167,7 @@ protected:
// Dirs // Dirs
MapDir="Maps"; MapDir="Maps";
QuestDir="quests"; QuestDir="quests";
PluginDir="plugins"; PluginDir="quests/plugins";
// Launcher // Launcher
LogPrefix = "logs/zone-"; LogPrefix = "logs/zone-";

View File

@ -83,8 +83,8 @@ Zone extensions and features
#ifdef QUEST_SCRIPTS_BYNAME #ifdef QUEST_SCRIPTS_BYNAME
//extends byname system to look in a templates directory //extends byname system to look in a templates directory
//independant of zone name //independant of zone name
#define QUEST_TEMPLATES_BYNAME #define QUEST_GLOBAL_BYNAME
#define QUEST_TEMPLATES_DIRECTORY "templates" #define QUEST_GLOBAL_DIRECTORY "global"
#endif #endif
//the min ratio at which a mob's speed is reduced //the min ratio at which a mob's speed is reduced

View File

@ -434,7 +434,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
//third look for /quests/templates/npcid.ext (precedence) //third look for /quests/templates/npcid.ext (precedence)
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += itoa(npcid); filename += itoa(npcid);
iter = _load_precedence.begin(); iter = _load_precedence.begin();
@ -455,7 +455,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
//fourth look for /quests/templates/npcname.ext (precedence) //fourth look for /quests/templates/npcname.ext (precedence)
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += npc_name; filename += npc_name;
iter = _load_precedence.begin(); iter = _load_precedence.begin();
@ -497,7 +497,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
//last look for /quests/templates/default.ext (precedence) //last look for /quests/templates/default.ext (precedence)
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += "default"; filename += "default";
iter = _load_precedence.begin(); iter = _load_precedence.begin();
@ -573,7 +573,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
//third look for /quests/templates/player.ext (precedence) //third look for /quests/templates/player.ext (precedence)
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += "player"; filename += "player";
iter = _load_precedence.begin(); iter = _load_precedence.begin();
@ -598,7 +598,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) { QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) {
// simply look for templates/global_npc.pl // simply look for templates/global_npc.pl
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += "global_npc"; filename += "global_npc";
std::string tmp; std::string tmp;
@ -626,7 +626,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena
QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) { QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) {
//first look for /quests/templates/player.ext (precedence) //first look for /quests/templates/player.ext (precedence)
filename = "quests/"; filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY; filename += QUEST_GLOBAL_DIRECTORY;
filename += "/"; filename += "/";
filename += "global_player"; filename += "global_player";
std::string tmp; std::string tmp;

View File

@ -1,11 +1,11 @@
#ifdef LUA_EQEMU #ifdef LUA_EQEMU
#include "lua.hpp"
#include "lua_parser.h" #include "lua_parser.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <sstream> #include <sstream>
#include "lua.hpp"
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
#include <boost/any.hpp> #include <boost/any.hpp>
@ -84,10 +84,13 @@ const char *LuaEvents[_LargestEventID] = {
extern Zone *zone; extern Zone *zone;
LuaParser::LuaParser() { LuaParser::LuaParser() {
L = nullptr;
} }
LuaParser::~LuaParser() { LuaParser::~LuaParser() {
ClearStates(); if(L) {
lua_close(L);
}
} }
int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
@ -128,15 +131,11 @@ int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string
int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
const char *sub_name = LuaEvents[evt]; const char *sub_name = LuaEvents[evt];
lua_State *L = nullptr; int start = lua_gettop(L);
auto iter = states_.find(package_name);
if(iter == states_.end()) {
return 0;
}
L = iter->second;
try { try {
lua_getfield(L, LUA_GLOBALSINDEX, sub_name); lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
lua_getfield(L, -1, sub_name);
//always push self //always push self
Lua_NPC l_npc(npc); Lua_NPC l_npc(npc);
@ -321,12 +320,20 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
if(lua_isnumber(L, -1)) { if(lua_isnumber(L, -1)) {
int ret = static_cast<int>(lua_tointeger(L, -1)); int ret = static_cast<int>(lua_tointeger(L, -1));
lua_pop(L, 2);
return ret; return ret;
} }
lua_pop(L, 2);
} catch(std::exception &ex) { } catch(std::exception &ex) {
printf("%s\n", ex.what()); printf("Lua call exception: %s\n", ex.what());
return 0;
//Restore our stack to the best of our ability
int end = lua_gettop(L);
int n = end - start;
if(n > 0) {
lua_pop(L, n);
}
} }
return 0; return 0;
@ -367,15 +374,11 @@ int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string d
int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data) { int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data) {
const char *sub_name = LuaEvents[evt]; const char *sub_name = LuaEvents[evt];
lua_State *L = nullptr; int start = lua_gettop(L);
auto iter = states_.find(package_name);
if(iter == states_.end()) {
return 0;
}
L = iter->second;
try { try {
lua_getfield(L, LUA_GLOBALSINDEX, sub_name); lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
lua_getfield(L, -1, sub_name);
//push self //push self
Lua_Client l_client(client); Lua_Client l_client(client);
@ -480,12 +483,20 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
if(lua_isnumber(L, -1)) { if(lua_isnumber(L, -1)) {
int ret = static_cast<int>(lua_tointeger(L, -1)); int ret = static_cast<int>(lua_tointeger(L, -1));
lua_pop(L, 2);
return ret; return ret;
} }
lua_pop(L, 2);
} catch(std::exception &ex) { } catch(std::exception &ex) {
printf("%s\n", ex.what()); printf("Lua call exception: %s\n", ex.what());
return 0;
//Restore our stack to the best of our ability
int end = lua_gettop(L);
int n = end - start;
if(n > 0) {
lua_pop(L, n);
}
} }
return 0; return 0;
@ -597,28 +608,22 @@ std::string LuaParser::GetVar(std::string name) {
} }
void LuaParser::ReloadQuests() { void LuaParser::ReloadQuests() {
ClearStates(); if(L) {
lua_close(L);
} }
void LuaParser::LoadScript(std::string filename, std::string package_name) { loaded_.clear();
auto iter = states_.find(package_name);
if(iter != states_.end()) {
return;
}
lua_State *L = luaL_newstate(); L = luaL_newstate();
luaL_openlibs(L); luaL_openlibs(L);
lua_pushnil(L); lua_pushnil(L);
lua_setglobal(L, "os"); lua_setglobal(L, "os");
//lua_pushnil(L);
//lua_setglobal(L, "io");
lua_getglobal(L, "package"); lua_getglobal(L, "package");
lua_getfield(L, -1, "path"); lua_getfield(L, -1, "path");
char module_path[1024]; char module_path[1024] = { 0 };
snprintf(module_path, 1024, "%s;%s", lua_tostring(L,-1), "quests/plugins/?.lua"); snprintf(module_path, 1023, "%s;%s", lua_tostring(L,-1), "quests/plugins/?.lua");
lua_pop(L, 1); lua_pop(L, 1);
lua_pushstring(L, module_path); lua_pushstring(L, module_path);
lua_setfield(L, -2, "path"); lua_setfield(L, -2, "path");
@ -637,6 +642,7 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
} }
//zone init - always loads after global //zone init - always loads after global
if(zone) {
std::string zone_script = "quests/" + std::string(zone->GetShortName()); std::string zone_script = "quests/" + std::string(zone->GetShortName());
zone_script += "/script_init.lua"; zone_script += "/script_init.lua";
f = fopen(zone_script.c_str(), "r"); f = fopen(zone_script.c_str(), "r");
@ -649,16 +655,42 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
return; return;
} }
} }
}
MapFunctions(L); MapFunctions(L);
}
if(luaL_dofile(L, filename.c_str())) { void LuaParser::LoadScript(std::string filename, std::string package_name) {
printf("Lua Error: %s\n", lua_tostring(L, -1)); auto iter = loaded_.find(package_name);
lua_close(L); if(iter != loaded_.end()) {
return; return;
} }
states_[package_name] = L; if(luaL_loadfile(L, filename.c_str())) {
printf("Lua Load Error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
lua_createtable(L, 0, 0); // anon table
lua_getglobal(L, "_G"); // get _G
lua_setfield(L, -2, "__index"); //anon table.__index = _G
lua_pushvalue(L, -1); //copy table to top of stack
lua_setmetatable(L, -2); //setmetatable(anon_table, copied table)
lua_pushvalue(L, -1); //put the table we made into the registry
lua_setfield(L, LUA_REGISTRYINDEX, package_name.c_str());
lua_setfenv(L, -2); //set the env to the table we made
if(lua_pcall(L, 0, 0, 0)) {
printf("Lua Load Error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
loaded_[package_name] = true;
} }
bool LuaParser::HasFunction(std::string subname, std::string package_name) { bool LuaParser::HasFunction(std::string subname, std::string package_name) {
@ -671,31 +703,23 @@ bool LuaParser::HasFunction(std::string subname, std::string package_name) {
subname[i] = c; subname[i] = c;
} }
auto iter = states_.find(package_name); auto iter = loaded_.find(package_name);
if(iter == states_.end()) { if(iter == loaded_.end()) {
return false; return false;
} }
lua_getfield(iter->second, LUA_GLOBALSINDEX, subname.c_str()); lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
if(lua_isfunction(iter->second, -1)) { lua_getfield(L, -1, subname.c_str());
if(lua_isfunction(L, -1)) {
lua_pop(L, 2);
return true; return true;
} }
lua_pop(L, 2);
return false; return false;
} }
void LuaParser::ClearStates() {
auto iter = states_.begin();
while(iter != states_.end()) {
if(iter->second) {
lua_close(iter->second);
}
++iter;
}
states_.clear();
}
void LuaParser::MapFunctions(lua_State *L) { void LuaParser::MapFunctions(lua_State *L) {
try { try {

View File

@ -52,7 +52,8 @@ private:
void MapFunctions(lua_State *L); void MapFunctions(lua_State *L);
std::map<std::string, std::string> vars_; std::map<std::string, std::string> vars_;
std::map<std::string, lua_State*> states_; std::map<std::string, bool> loaded_;
lua_State *L;
}; };
#endif #endif

View File

@ -169,6 +169,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
LogFile->write(EQEMuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort); LogFile->write(EQEMuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort);
LogFile->write(EQEMuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID); LogFile->write(EQEMuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID);
parse->ReloadQuests(true);
UpdateWindowTitle(); UpdateWindowTitle();
zone->GetTimeSync(); zone->GetTimeSync();
@ -879,7 +880,7 @@ void Zone::Shutdown(bool quite)
zone->ResetAuth(); zone->ResetAuth();
safe_delete(zone); safe_delete(zone);
dbasync->CommitWrites(); dbasync->CommitWrites();
if(parse) { parse->ReloadQuests(true); } parse->ReloadQuests(true);
UpdateWindowTitle(); UpdateWindowTitle();
} }