Server upload

RD Core / Commit #2

Commit Server upload

Alex Alex committed 18/10/2026 23:38 main Patch
1,106 files +223,404 -0
A src/events.h +116-0 View file
@@ -0,0 +1,116 @@
1+/**
2+ * The Forgotten Server - a free and open-source MMORPG server emulator
3+ * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; either version 2 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program; if not, write to the Free Software Foundation, Inc.,
17+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+ */
19+
20+#ifndef FS_EVENTS_H_BD444CC0EE167E5777E4C90C766B36DC
21+#define FS_EVENTS_H_BD444CC0EE167E5777E4C90C766B36DC
22+
23+#include "luascript.h"
24+#include "const.h"
25+
26+class Party;
27+class ItemType;
28+class Tile;
29+
30+class Events
31+{
32+ struct EventsInfo {
33+ // Creature
34+ int32_t creatureOnChangeOutfit = -1;
35+ int32_t creatureOnAreaCombat = -1;
36+ int32_t creatureOnTargetCombat = -1;
37+ int32_t creatureOnHear = -1;
38+
39+ // Party
40+ int32_t partyOnJoin = -1;
41+ int32_t partyOnLeave = -1;
42+ int32_t partyOnDisband = -1;
43+ int32_t partyOnShareExperience = -1;
44+
45+ // Player
46+ int32_t playerOnBrowseField = -1;
47+ int32_t playerOnLook = -1;
48+ int32_t playerOnLookInBattleList = -1;
49+ int32_t playerOnLookInTrade = -1;
50+ int32_t playerOnLookInShop = -1;
51+ int32_t playerOnMoveItem = -1;
52+ int32_t playerOnItemMoved = -1;
53+ int32_t playerOnMoveCreature = -1;
54+ int32_t playerOnReportRuleViolation = -1;
55+ int32_t playerOnReportBug = -1;
56+ int32_t playerOnTurn = -1;
57+ int32_t playerOnTradeRequest = -1;
58+ int32_t playerOnTradeAccept = -1;
59+ int32_t playerOnTradeCompleted = -1;
60+ int32_t playerOnGainExperience = -1;
61+ int32_t playerOnLoseExperience = -1;
62+ int32_t playerOnGainSkillTries = -1;
63+ int32_t playerOnWrapItem = -1;
64+
65+ // Monster
66+ int32_t monsterOnDropLoot = -1;
67+ int32_t monsterOnSpawn = -1;
68+ };
69+
70+ public:
71+ Events();
72+
73+ bool load();
74+
75+ // Creature
76+ bool eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t& outfit);
77+ ReturnValue eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive);
78+ ReturnValue eventCreatureOnTargetCombat(Creature* creature, Creature* target);
79+ void eventCreatureOnHear(Creature* creature, Creature* speaker, const std::string& words, SpeakClasses type);
80+
81+ // Party
82+ bool eventPartyOnJoin(Party* party, Player* player);
83+ bool eventPartyOnLeave(Party* party, Player* player);
84+ bool eventPartyOnDisband(Party* party);
85+ void eventPartyOnShareExperience(Party* party, uint64_t& exp);
86+
87+ // Player
88+ bool eventPlayerOnBrowseField(Player* player, const Position& position);
89+ void eventPlayerOnLook(Player* player, const Position& position, Thing* thing, uint8_t stackpos, int32_t lookDistance);
90+ void eventPlayerOnLookInBattleList(Player* player, Creature* creature, int32_t lookDistance);
91+ void eventPlayerOnLookInTrade(Player* player, Player* partner, Item* item, int32_t lookDistance);
92+ bool eventPlayerOnLookInShop(Player* player, const ItemType* itemType, uint8_t count);
93+ bool eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, const Position& fromPosition, const Position& toPosition, Cylinder* fromCylinder, Cylinder* toCylinder);
94+ void eventPlayerOnItemMoved(Player* player, Item* item, uint16_t count, const Position& fromPosition, const Position& toPosition, Cylinder* fromCylinder, Cylinder* toCylinder);
95+ bool eventPlayerOnMoveCreature(Player* player, Creature* creature, const Position& fromPosition, const Position& toPosition);
96+ void eventPlayerOnReportRuleViolation(Player* player, const std::string& targetName, uint8_t reportType, uint8_t reportReason, const std::string& comment, const std::string& translation);
97+ bool eventPlayerOnReportBug(Player* player, const std::string& message, const Position& position, uint8_t category);
98+ bool eventPlayerOnTurn(Player* player, Direction direction);
99+ bool eventPlayerOnTradeRequest(Player* player, Player* target, Item* item);
100+ bool eventPlayerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem);
101+ void eventPlayerOnTradeCompleted(Player* player, Player* target, Item* item, Item* targetItem, bool isSuccess);
102+ void eventPlayerOnGainExperience(Player* player, Creature* source, uint64_t& exp, uint64_t rawExp);
103+ void eventPlayerOnLoseExperience(Player* player, uint64_t& exp);
104+ void eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t& tries);
105+ void eventPlayerOnWrapItem(Player* player, Item* item);
106+
107+ // Monster
108+ void eventMonsterOnDropLoot(Monster* monster, Container* corpse);
109+ bool eventMonsterOnSpawn(Monster* monster, const Position& position, bool startup, bool artificial);
110+
111+ private:
112+ LuaScriptInterface scriptInterface;
113+ EventsInfo info;
114+};
115+
116+#endif
A src/fileloader.cpp +124-0 View file
@@ -0,0 +1,124 @@
1+/**
2+ * The Forgotten Server - a free and open-source MMORPG server emulator
3+ * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; either version 2 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program; if not, write to the Free Software Foundation, Inc.,
17+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+ */
19+
20+#include "otpch.h"
21+
22+#include <stack>
23+#include "fileloader.h"
24+
25+
26+namespace OTB {
27+
28+constexpr Identifier wildcard = {{'\0', '\0', '\0', '\0'}};
29+
30+Loader::Loader(const std::string& fileName, const Identifier& acceptedIdentifier):
31+ fileContents(fileName)
32+{
33+ constexpr auto minimalSize = sizeof(Identifier) + sizeof(Node::START) + sizeof(Node::type) + sizeof(Node::END);
34+ if (fileContents.size() <= minimalSize) {
35+ throw InvalidOTBFormat{};
36+ }
37+
38+ Identifier fileIdentifier;
39+ std::copy(fileContents.begin(), fileContents.begin() + fileIdentifier.size(), fileIdentifier.begin());
40+ if (fileIdentifier != acceptedIdentifier && fileIdentifier != wildcard) {
41+ throw InvalidOTBFormat{};
42+ }
43+}
44+
45+using NodeStack = std::stack<Node*, std::vector<Node*>>;
46+static Node& getCurrentNode(const NodeStack& nodeStack) {
47+ if (nodeStack.empty()) {
48+ throw InvalidOTBFormat{};
49+ }
50+ return *nodeStack.top();
51+}
52+
53+const Node& Loader::parseTree()
54+{
55+ auto it = fileContents.begin() + sizeof(Identifier);
56+ if (static_cast<uint8_t>(*it) != Node::START) {
57+ throw InvalidOTBFormat{};
58+ }
59+ root.type = *(++it);
60+ root.propsBegin = ++it;
61+ NodeStack parseStack;
62+ parseStack.push(&root);
63+
64+ for (; it != fileContents.end(); ++it) {
65+ switch(static_cast<uint8_t>(*it)) {
66+ case Node::START: {
67+ auto& currentNode = getCurrentNode(parseStack);
68+ if (currentNode.children.empty()) {
69+ currentNode.propsEnd = it;
70+ }
71+ currentNode.children.emplace_back();
72+ auto& child = currentNode.children.back();
73+ if (++it == fileContents.end()) {
74+ throw InvalidOTBFormat{};
75+ }
76+ child.type = *it;
77+ child.propsBegin = it + sizeof(Node::type);
78+ parseStack.push(&child);
79+ break;
80+ }
81+ case Node::END: {
82+ auto& currentNode = getCurrentNode(parseStack);
83+ if (currentNode.children.empty()) {
84+ currentNode.propsEnd = it;
85+ }
86+ parseStack.pop();
87+ break;
88+ }
89+ case Node::ESCAPE: {
90+ if (++it == fileContents.end()) {
91+ throw InvalidOTBFormat{};
92+ }
93+ break;
94+ }
95+ default: {
96+ break;
97+ }
98+ }
99+ }
100+ if (!parseStack.empty()) {
101+ throw InvalidOTBFormat{};
102+ }
103+
104+ return root;
105+}
106+
107+bool Loader::getProps(const Node& node, PropStream& props)
108+{
109+ auto size = std::distance(node.propsBegin, node.propsEnd);
110+ if (size == 0) {
111+ return false;
112+ }
113+ propBuffer.resize(size);
114+ bool lastEscaped = false;
115+
116+ auto escapedPropEnd = std::copy_if(node.propsBegin, node.propsEnd, propBuffer.begin(), [&lastEscaped](const char& byte) {
117+ lastEscaped = byte == static_cast<char>(Node::ESCAPE) && !lastEscaped;
118+ return !lastEscaped;
119+ });
120+ props.init(&propBuffer[0], std::distance(propBuffer.begin(), escapedPropEnd));
121+ return true;
122+}
123+
124+} //namespace OTB
A src/fileloader.h +167-0 View file
@@ -0,0 +1,167 @@
1+/**
2+ * The Forgotten Server - a free and open-source MMORPG server emulator
3+ * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; either version 2 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program; if not, write to the Free Software Foundation, Inc.,
17+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+ */
19+
20+#ifndef FS_FILELOADER_H_9B663D19E58D42E6BFACFE5B09D7A05E
21+#define FS_FILELOADER_H_9B663D19E58D42E6BFACFE5B09D7A05E
22+
23+#include <limits>
24+#include <vector>
25+#include <boost/iostreams/device/mapped_file.hpp>
26+
27+class PropStream;
28+
29+namespace OTB {
30+using MappedFile = boost::iostreams::mapped_file_source;
31+using ContentIt = MappedFile::iterator;
32+using Identifier = std::array<char, 4>;
33+
34+struct Node
35+{
36+ using ChildrenVector = std::vector<Node>;
37+
38+ ChildrenVector children;
39+ ContentIt propsBegin;
40+ ContentIt propsEnd;
41+ uint8_t type;
42+ enum NodeChar: uint8_t
43+ {
44+ ESCAPE = 0xFD,
45+ START = 0xFE,
46+ END = 0xFF,
47+ };
48+};
49+
50+struct LoadError : std::exception {
51+ const char* what() const noexcept override = 0;
52+};
53+
54+struct InvalidOTBFormat final : LoadError {
55+ const char* what() const noexcept override {
56+ return "Invalid OTBM file format";
57+ }
58+};
59+
60+class Loader {
61+ MappedFile fileContents;
62+ Node root;
63+ std::vector<char> propBuffer;
64+public:
65+ Loader(const std::string& fileName, const Identifier& acceptedIdentifier);
66+ bool getProps(const Node& node, PropStream& props);
67+ const Node& parseTree();
68+};
69+
70+} //namespace OTB
71+
72+class PropStream
73+{
74+ public:
75+ void init(const char* a, size_t size) {
76+ p = a;
77+ end = a + size;
78+ }
79+
80+ size_t size() const {
81+ return end - p;
82+ }
83+
84+ template <typename T>
85+ bool read(T& ret) {
86+ if (size() < sizeof(T)) {
87+ return false;
88+ }
89+
90+ memcpy(&ret, p, sizeof(T));
91+ p += sizeof(T);
92+ return true;
93+ }
94+
95+ bool readString(std::string& ret) {
96+ uint16_t strLen;
97+ if (!read<uint16_t>(strLen)) {
98+ return false;
99+ }
100+
101+ if (size() < strLen) {
102+ return false;
103+ }
104+
105+ char* str = new char[strLen + 1];
106+ memcpy(str, p, strLen);
107+ str[strLen] = 0;
108+ ret.assign(str, strLen);
109+ delete[] str;
110+ p += strLen;
111+ return true;
112+ }
113+
114+ bool skip(size_t n) {
115+ if (size() < n) {
116+ return false;
117+ }
118+
119+ p += n;
120+ return true;
121+ }
122+
123+ private:
124+ const char* p = nullptr;
125+ const char* end = nullptr;
126+};
127+
128+class PropWriteStream
129+{
130+ public:
131+ PropWriteStream() = default;
132+
133+ // non-copyable
134+ PropWriteStream(const PropWriteStream&) = delete;
135+ PropWriteStream& operator=(const PropWriteStream&) = delete;
136+
137+ const char* getStream(size_t& size) const {
138+ size = buffer.size();
139+ return buffer.data();
140+ }
141+
142+ void clear() {
143+ buffer.clear();
144+ }
145+
146+ template <typename T>
147+ void write(T add) {
148+ char* addr = reinterpret_cast<char*>(&add);
149+ std::copy(addr, addr + sizeof(T), std::back_inserter(buffer));
150+ }
151+
152+ void writeString(const std::string& str) {
153+ size_t strLength = str.size();
154+ if (strLength > std::numeric_limits<uint16_t>::max()) {
155+ write<uint16_t>(0);
156+ return;
157+ }
158+
159+ write(static_cast<uint16_t>(strLength));
160+ std::copy(str.begin(), str.end(), std::back_inserter(buffer));
161+ }
162+
163+ private:
164+ std::vector<char> buffer;
165+};
166+
167+#endif
Top