Skip to content

Commit

Permalink
feat: GameWingsAurasEffects connection server (#1)
Browse files Browse the repository at this point in the history
* init with bug

* fix compilation

* fix missin packet

* update lua
  • Loading branch information
kokekanon authored Apr 22, 2024
1 parent 7764f37 commit 77f80d5
Show file tree
Hide file tree
Showing 38 changed files with 2,648 additions and 12 deletions.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,69 @@ If you need help, please visit the [support forum on OTLand](https://otland.net/
### Issues

We use the [issue tracker on GitHub](https://github.com/otland/forgottenserver/issues). Keep in mind that everyone who is watching the repository gets notified by e-mail when there is activity, so be thoughtful and avoid writing comments that aren't meaningful for an issue (e.g. "+1"). If you'd like for an issue to be fixed faster, you should either fix it yourself and submit a pull request, or place a bounty on the issue.

Client:
```lua
g_game.enableFeature(GameWingsAurasEffectsShader)
g_game.enableFeature(GameFormatCreatureName)
g_game.enableFeature(GameCreatureShader)
g_game.enableFeature(GameCreatureAttachedEffect)
g_game.enableFeature(GameItemShader)
g_game.enableFeature(GameItemTooltipV8);
```
DATA BASE
```sql
ALTER TABLE `players`
ADD COLUMN `currentwing` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizewing` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currentaura` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeaura` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currenteffect` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeeffect` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currentshader` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeshader` tinyint NOT NULL DEFAULT '0';
```


```sql
ALTER TABLE `players`
ADD COLUMN `currentwing` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizewing` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currentaura` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeaura` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currenteffect` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeeffect` tinyint NOT NULL DEFAULT '0',
ADD COLUMN `currentshader` smallint UNSIGNED NOT NULL DEFAULT '0',
ADD COLUMN `randomizeshader` tinyint NOT NULL DEFAULT '0';
```
```sql
CREATE TABLE IF NOT EXISTS `player_wings` (
`player_id` int NOT NULL DEFAULT '0',
`wing_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`wing_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_effects` (
`player_id` int NOT NULL DEFAULT '0',
`effect_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`effect_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_auras` (
`player_id` int NOT NULL DEFAULT '0',
`aura_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`aura_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_shaders` (
`player_id` int(11) NOT NULL DEFAULT 0,
`shader_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`player_id`, `shader_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
```

![img](https://github.com/Nottinghster/otclient/assets/114332266/782e0fcf-b1cf-451e-b102-d7e7943bd50b)
4 changes: 4 additions & 0 deletions data/XML/auras.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<auras>
<aura id="8" name="3 aura" speed="20" />
</auras>
4 changes: 4 additions & 0 deletions data/XML/effects.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<effects>
<effect id="7" name="1 effect" speed="20" />
</effects>
9 changes: 9 additions & 0 deletions data/XML/shaders.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<shaders>
<shader id="1" name="Outfit - Rainbow" premium="no" />
<shader id="2" name="Outfit - Ghost" premium="no" />
<shader id="3" name="Outfit - Jelly" premium="no" />
<shader id="4" name="Outfit - Fragmented" premium="no" />
<shader id="5" name="Outfit - Outline" premium="no" />

</shaders>
5 changes: 5 additions & 0 deletions data/XML/wings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<wings>
<wing id="2" name="1 wings" speed="20" />
<wing id="11" name="11 wings" speed="20" />
</wings>
2 changes: 1 addition & 1 deletion data/monster/monsters/orc.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<monster name="Orc" nameDescription="an orc" race="blood" experience="25" speed="150" manacost="300">
<monster name="Orc" nameDescription="an orc" race="blood" experience="25" speed="150" manacost="300" raceId="5" shaderEffect = "Outfit - Rainbow" auraEffect = "8" wignsEffect ="11" rayosEffect="7" >
<health now="70" max="70" />
<look type="5" corpse="5966" />
<targetchange interval="4000" chance="0" />
Expand Down
92 changes: 92 additions & 0 deletions data/scripts/OTCMEHAH/Attachedeffect.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
local mehah = {
talkactions = {
attacheffect = "!attacheffect",
detachEffect = "!detacheffect",
playerSetShader = "!playerSetShader",
itemSetShader = "!itemSetShader",
mapShader = "!mapShader"
},
}

local events = {}

local function processCommand(player, words, param, type, action)
if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then
player:sendCancelMessage("No tienes acceso a este comando.")
return false
end

local params, arg
if param:find("\"") then
params = { param:match("\"(.+)\",*(.*)") }
arg = params[1]
print(params)
print(arg)
pdump(params)
else
params = param:split(", ")
arg = params[1]
print("2",params)
print("2",arg)
end

if not arg then
player:sendCancelMessage("Parámetro inválido. Por favor proporciona un argumento válido.")
return false
end

local creature
if params[2] and params[2] ~= "" then
creature = Player(params[2])
if not creature then
player:sendCancelMessage("El nombre del jugador proporcionado no es válido.")
return false
end
else
creature = player
end

action(creature, arg)
return false
end

local attachEffect = TalkAction(mehah.talkactions.attacheffect)
function attachEffect.onSay(player, words, param, type)
return processCommand(player, words, param, type, function(creature, effect)
creature:attachEffectById(tonumber(effect), false)
end)
end
table.insert(events, attachEffect)

local detachEffect = TalkAction(mehah.talkactions.detachEffect)
function detachEffect.onSay(player, words, param, type)
return processCommand(player, words, param, type, function(creature, effect)
creature:detachEffectById(tonumber(effect))
end)
end
table.insert(events, detachEffect)

local setShader = TalkAction(mehah.talkactions.playerSetShader)
function setShader.onSay(player, words, param, type)
return processCommand(player, words, param, type, function(creature, shader)
creature:setShader(shader)
end)
end
table.insert(events, setShader)

local mapShader = TalkAction(mehah.talkactions.mapShader)
function mapShader.onSay(player, words, param, type)
return processCommand(player, words, param, type, function(creature, shader)
if creature:getMapShader() ~= shader then
creature:setMapShader(shader, true)
end
end)
end
table.insert(events, mapShader)

for _, event in ipairs(events) do
event:accountType(ACCOUNT_TYPE_GOD)
event:access(true)
event:separator(" ")
event:register()
end
12 changes: 12 additions & 0 deletions data/talkactions/scripts/reload.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ local reloadTypes = {

["mount"] = RELOAD_TYPE_MOUNTS,
["mounts"] = RELOAD_TYPE_MOUNTS,

["wing"] = RELOAD_TYPE_WINGS,
["wings"] = RELOAD_TYPE_WINGS,

["effect"] = RELOAD_TYPE_EFFECT,
["effects"] = RELOAD_TYPE_EFFECT,

["aura"] = RELOAD_TYPE_AURA,
["auras"] = RELOAD_TYPE_AURA,

["shader"] = RELOAD_TYPE_SHADERS,
["shaders"] = RELOAD_TYPE_SHADERS,

["move"] = RELOAD_TYPE_MOVEMENTS,
["movement"] = RELOAD_TYPE_MOVEMENTS,
Expand Down
36 changes: 36 additions & 0 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ CREATE TABLE IF NOT EXISTS `players` (
`offlinetraining_time` smallint unsigned NOT NULL DEFAULT '43200',
`offlinetraining_skill` int NOT NULL DEFAULT '-1',
`stamina` smallint unsigned NOT NULL DEFAULT '2520',
`currentwing` smallint UNSIGNED NOT NULL DEFAULT '0',
`randomizewing` tinyint NOT NULL DEFAULT '0',
`currentaura` smallint UNSIGNED NOT NULL DEFAULT '0',
`randomizeaura` tinyint NOT NULL DEFAULT '0',
`currenteffect` smallint UNSIGNED NOT NULL DEFAULT '0',
`randomizeeffect` tinyint NOT NULL DEFAULT '0',
`currentshader` smallint UNSIGNED NOT NULL DEFAULT '0',
`randomizeshader` tinyint NOT NULL DEFAULT '0';
`skill_fist` int unsigned NOT NULL DEFAULT 10,
`skill_fist_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_club` int unsigned NOT NULL DEFAULT 10,
Expand Down Expand Up @@ -341,6 +349,34 @@ CREATE TABLE IF NOT EXISTS `server_config` (
PRIMARY KEY `config` (`config`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_wings` (
`player_id` int NOT NULL DEFAULT '0',
`wing_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`wing_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_effects` (
`player_id` int NOT NULL DEFAULT '0',
`effect_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`effect_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_auras` (
`player_id` int NOT NULL DEFAULT '0',
`aura_id` smallint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`aura_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `player_shaders` (
`player_id` int(11) NOT NULL DEFAULT 0,
`shader_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`player_id`, `shader_id`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

CREATE TABLE IF NOT EXISTS `tile_store` (
`house_id` int NOT NULL,
`data` longblob NOT NULL,
Expand Down
64 changes: 64 additions & 0 deletions src/auras.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2023 The Forgotten Server Authors. All rights reserved.
// Use of this source code is governed by the GPL-2.0 License that can be found in the LICENSE file.

#include "otpch.h"

#include "auras.h"

#include "pugicast.h"
#include "tools.h"

bool Auras::reload()
{
auras.clear();
return loadFromXml();
}

bool Auras::loadFromXml()
{
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("data/XML/auras.xml");
if (!result) {
printXMLError("Error - Auras::loadFromXml", "data/XML/auras.xml", result);
return false;
}

for (auto auraNode : doc.child("auras").children()) {
uint16_t nodeId = pugi::cast<uint16_t>(auraNode.attribute("id").value());
if (nodeId == 0 || nodeId > std::numeric_limits<uint16_t>::max()) {
std::cout << "[Notice - Auras::loadFromXml] Aura id "" << nodeId << "" is not within 1 and 65535 range"
<< std::endl;
continue;
}

if (getAuraByID(nodeId)) {
std::cout << "[Notice - Auras::loadFromXml] Duplicate aura with id: " << nodeId << std::endl;
continue;
}

auras.emplace_back(
static_cast<uint16_t>(nodeId),
auraNode.attribute("name").as_string(), pugi::cast<int32_t>(auraNode.attribute("speed").value()),
auraNode.attribute("premium").as_bool());
}
auras.shrink_to_fit();
return true;
}

Aura* Auras::getAuraByID(uint16_t id)
{
auto it = std::find_if(auras.begin(), auras.end(), [id](const Aura& aura) { return aura.id == id; });

return it != auras.end() ? &*it : nullptr;
}

Aura* Auras::getAuraByName(std::string_view name)
{
for (auto& it : auras) {
if (strcasecmp(name.data(), it.name.c_str()) == 0) {
return &it;
}
}

return nullptr;
}
35 changes: 35 additions & 0 deletions src/auras.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2023 The Forgotten Server Authors. All rights reserved.
// Use of this source code is governed by the GPL-2.0 License that can be found in the LICENSE file.

#ifndef FS_AURAS_H
#define FS_AURAS_H

struct Aura
{
Aura(uint16_t id, std::string_view name, int32_t speed, bool premium) :
name{name}, speed{speed}, id{id}, premium{premium}
{}

std::string name;
int32_t speed;

uint16_t id;
bool premium;
};

class Auras
{
public:
bool reload();
bool loadFromXml();
Aura* getAuraByID(uint16_t id);
Aura* getAuraByName(std::string_view name);


const std::vector<Aura>& getAuras() const { return auras; }

private:
std::vector<Aura> auras;
};

#endif // FS_AURAS_H
2 changes: 1 addition & 1 deletion src/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ bool ConfigManager::load()
integer[EXP_FROM_PLAYERS_LEVEL_RANGE] = getGlobalNumber(L, "expFromPlayersLevelRange", 75);
integer[CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES] = getGlobalNumber(L, "checkExpiredMarketOffersEachMinutes", 60);
integer[MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER] = getGlobalNumber(L, "maxMarketOffersAtATimePerPlayer", 100);
integer[MAX_PACKETS_PER_SECOND] = getGlobalNumber(L, "maxPacketsPerSecond", 25);
integer[MAX_PACKETS_PER_SECOND] = getGlobalNumber(L, "maxPacketsPerSecond", 50);
integer[SERVER_SAVE_NOTIFY_DURATION] = getGlobalNumber(L, "serverSaveNotifyDuration", 5);
integer[YELL_MINIMUM_LEVEL] = getGlobalNumber(L, "yellMinimumLevel", 2);
integer[VIP_FREE_LIMIT] = getGlobalNumber(L, "vipFreeLimit", 20);
Expand Down
6 changes: 5 additions & 1 deletion src/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#ifndef FS_CONST_H_0A49B5996F074465BF44B90F4F780E8B
#define FS_CONST_H_0A49B5996F074465BF44B90F4F780E8B

static constexpr int32_t NETWORKMESSAGE_MAXSIZE = 24590;
static constexpr int32_t NETWORKMESSAGE_MAXSIZE = 65500;

enum MagicEffectClasses : uint8_t {
CONST_ME_NONE,
Expand Down Expand Up @@ -544,6 +544,10 @@ enum ReloadTypes_t : uint8_t {
RELOAD_TYPE_ITEMS,
RELOAD_TYPE_MONSTERS,
RELOAD_TYPE_MOUNTS,
RELOAD_TYPE_WINGS,
RELOAD_TYPE_AURAS,
RELOAD_TYPE_EFFECTS,
RELOAD_TYPE_SHADERS,
RELOAD_TYPE_MOVEMENTS,
RELOAD_TYPE_NPCS,
RELOAD_TYPE_QUESTS,
Expand Down
Loading

1 comment on commit 77f80d5

@kokekanon
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protocolgame.cpp

	if (accountName.empty()) {
		disconnectClient("You must enter your account name.");
		return;
	}
	std::string characterName = msg.getString();
	uint32_t timeStamp = msg.get<uint32_t>();
	uint8_t randNumber = msg.getByte();
	if (challengeTimestamp != timeStamp || challengeRandom != randNumber) {
		disconnect();
		return;
	}
+
+	if (operatingSystem == CLIENTOS_OTCLIENT_WINDOWS) {
+		isMehah = true;
+	}
+
	if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) {
		disconnectClient(fmt::format("Only clients with protocol {:s} allowed!", CLIENT_VERSION_STR));
		return;
	}
	if (g_game.getGameState() == GAME_STATE_STARTUP) {
		disconnectClient("Gameworld is starting up. Please wait.");
		return;
	}

protocolgame.h

		std::unordered_set<uint32_t> knownCreatureSet;
		Player* player = nullptr;
		uint32_t eventConnect = 0;
		uint32_t challengeTimestamp = 0;
		uint16_t version = CLIENT_VERSION_MIN;
		uint8_t challengeRandom = 0;

		bool debugAssertSent = false;
		bool acceptPackets = false;
+		bool isMehah = false;
};

#endif

Please sign in to comment.