Jump to content

Recommended Posts

  • Active+ Member

This is the hidden content, please

Another Download : 

This is the hidden content, please

BlendItemRenewal

Completely new and fresh approach to load blend items using JSON.

Better than previous versions?

I suppose so. The source file for this version has only about 50 lines so it is very slim.

I have decided to adhere to the YMIR coding style, so there are no classes or structures.

So - how to install this „system”?

  • Make sure the compiler you are using supports (at least) C++11.
    • Install 
      This is the hidden content, please
       parser.
      • Replace blend_item.h and blend_item.cpp with the old ones, and that is it.
        • If you want hot-reloading the JSON file, you can add the cmd_gm.cpp part (recommended).

Example blend.json file content below.

{
	"50821": {
		"type": "CRITICAL_PCT",
		"value": [ 8, 10, 12, 15, 20 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"50822": {
		"type": "PENETRATE_PCT",
		"value": [ 8, 10, 12, 15, 20 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"50823": {
		"type": "ATTACK_SPEED",
		"value": [ 2, 3, 4, 5, 8 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"50824": {
		"type": "RESIST_MAGIC",
		"value": [ 8, 10, 12, 15, 20 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"50825": {
		"type": "ATT_BONUS",
		"value": [ 30, 50, 70, 90, 120 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"50826": {
		"type": "DEF_BONUS",
		"value": [ 40, 70, 100, 150, 200 ],
		"duration": [ 60, 120, 180, 300, 600 ]
	},

	"51002": {
		"type": "ENERGY",
		"value": [ 1, 3, 5, 7, 10 ],
		"duration": 1800 // It is possible to use only one duration (and value).
	}
}
  • Metin2 Dev 135
  • Eyes 6
  • Scream 1
  • Good 21
  • Love 1
  • Love 38
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/
Share on other sites

  • Premium

Good stuff, but I've got it already for 30 minutes. You should use map instead of vector to save some time on finding the right blend data in you data pool. Nice to see people getting rid of some old and ugly code. 

  • Good 2
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155867
Share on other sites

  • Active+ Member
12 minutes ago, filipw1 said:

Good stuff, but I've got it already for 30 minutes. You should use map instead of vector to save some time on finding the right blend data in you data pool. Nice to see people getting rid of some old and ugly code. 

You should fix all your systems to comments my topics!!! Thanks, fixed.

Edited by Thorek
  • Angry 1
  • Lmao 1
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155868
Share on other sites

  • Active+ Member
8 minutes ago, BadRomani said:

spacer.png

spacer.png

Wops, sorry - contains function comes from C++20.

Change return in CBlendItem::Find to return items.find(item) != items.end();

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Love 1
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155876
Share on other sites

2 minutes ago, Thorek said:

Wops, sorry - contains function comes from C++20.

Change return in CBlendItem::Find to return items.find(item) != items.end();

Thank you bro. Thanks to your help, the build was created successfully.

        "value": [ 1, 3, 5, 7, 10 ],
        "duration": [ 1800, 1800, 1800,180 1800 ]

when used in this way, the server will not boot.

        "value": [ 1, 3 ],
        "duration": [ 1800, 1800 ]

This is how the server opens.

 

How can I add more? As in blend.txt.

Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155877
Share on other sites

  • Active+ Member
40 minutes ago, BadRomani said:

Thank you bro. Thanks to your help, the build was created successfully.

        "value": [ 1, 3, 5, 7, 10 ],
        "duration": [ 1800, 1800, 1800,180 1800 ]

when used in this way, the server will not boot.

        "value": [ 1, 3 ],
        "duration": [ 1800, 1800 ]

This is how the server opens.

 

How can I add more? As in blend.txt.

After every item in JSON array, you must put a comma (except for the last one).

For example, if you have: [ 1800, 1800, 1800,180 1800 ]

Server not booting because after 180 comma wasn't found.

Edited by Thorek
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155880
Share on other sites

15 minutes ago, Thorek said:

After every item in JSON array, you must put a comma (except for the last one).

For example, if you have: [ 1800, 1800, 1800,180 1800 ]

Server not booting because after 180 comma wasn't found.

I made a mistake while editing ? Ok, now the server is opening.

Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-155881
Share on other sites

  • 1 year later...
  • Active+ Member
On 5/2/2024 at 12:15 AM, Assembly said:

@ThorekWhat if we want to give more than one enchantment?

Well, if you want do this like YMIR, you can extend sockets count.

On 5/2/2024 at 5:46 AM, josehdelaro said:

ty some problems but work

What problems? I'll take a look.

Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-165069
Share on other sites

  • 5 months later...

Thanks but Marty using rapidjson and its more fast than nlohmann, so better is have better compatibility than 100 libraries into extern..

For rapidjson:

blend_item.cpp
Spoiler
#include "stdafx.h"
#include "constants.h"
#include "blend_item.h"
#include "locale_service.h"

#include <rapidjson/document.h>
#include <rapidjson/filereadstream.h>
#include <rapidjson/error/en.h>
#include <cstdio>
#include <string>

rapidjson::Document container;

bool Blend_Item_init()
{
	try
	{
		std::string path = LocaleService_GetBasePath() + "/blend.json";
		FILE* fp = fopen(path.c_str(), "rb");
		if (!fp)
		{
			sys_err("Cannot open file: %s", path.c_str());
			return false;
		}

		char readBuffer[65536];
		rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));

		container.ParseStream(is);
		fclose(fp);

		if (container.HasParseError())
		{
			sys_err("JSON parse error: %s (%u)", rapidjson::GetParseError_En(container.GetParseError()), container.GetErrorOffset());
			return false;
		}

		return true;
	}
	catch (const std::exception& e)
	{
		sys_err("%s", e.what());
		return false;
	}
}

bool Blend_Item_find(const uint32_t item)
{
	return container.HasMember(std::to_string(item).c_str());
}

void Blend_Item_set_value(const LPITEM item)
{
	if (!item)
		return;

	const std::string itemStr = std::to_string(item->GetVnum());
	if (!container.HasMember(itemStr.c_str()))
		return;

	const rapidjson::Value& result = container[itemStr.c_str()];

	if (result.HasMember("type"))
	{
		const auto& type = result["type"];
		if (type.IsInt())
		{
			item->SetSocket(0, type.GetInt());
		}
		else if (type.IsString())
		{
			item->SetSocket(0, FN_get_apply_type(type.GetString()));
		}
	}

	if (result.HasMember("value"))
	{
		const auto& value = result["value"];
		if (value.IsArray())
		{
			int index = number(0, value.Size() - 1);
			item->SetSocket(1, value[index].GetInt());
		}
		else if (value.IsInt())
		{
			item->SetSocket(1, value.GetInt());
		}
	}

	if (result.HasMember("duration"))
	{
		const auto& duration = result["duration"];
		if (duration.IsArray())
		{
			int index = number(0, duration.Size() - 1);
			item->SetSocket(2, duration[index].GetInt());
		}
		else if (duration.IsInt())
		{
			item->SetSocket(2, duration.GetInt());
		}
	}
}

 

blend_item.h
Spoiler
#pragma once

#include "item.h"
#include <cstdint>

bool Blend_Item_init();
bool Blend_Item_find(uint32_t item);
void Blend_Item_set_value(LPITEM item);

 

cmd_gm.cpp
Spoiler
#include "blend_item.h"

case 'b':
	if (Blend_Item_init())
		ch->ChatPacket(CHAT_TYPE_INFO, "<Blend> Reloaded!");
	else
		ch->ChatPacket(CHAT_TYPE_INFO, "Error Reloading <Blend>!");
	break;

 

 

Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-167731
Share on other sites

  • Active+ Member
20 hours ago, Filachilla said:

Thanks but Marty using rapidjson and its more fast than nlohmann, so better is have better compatibility than 100 libraries into extern..

For rapidjson:

blend_item.cpp
  Reveal hidden contents
#include "stdafx.h"
#include "constants.h"
#include "blend_item.h"
#include "locale_service.h"

#include <rapidjson/document.h>
#include <rapidjson/filereadstream.h>
#include <rapidjson/error/en.h>
#include <cstdio>
#include <string>

rapidjson::Document container;

bool Blend_Item_init()
{
	try
	{
		std::string path = LocaleService_GetBasePath() + "/blend.json";
		FILE* fp = fopen(path.c_str(), "rb");
		if (!fp)
		{
			sys_err("Cannot open file: %s", path.c_str());
			return false;
		}

		char readBuffer[65536];
		rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));

		container.ParseStream(is);
		fclose(fp);

		if (container.HasParseError())
		{
			sys_err("JSON parse error: %s (%u)", rapidjson::GetParseError_En(container.GetParseError()), container.GetErrorOffset());
			return false;
		}

		return true;
	}
	catch (const std::exception& e)
	{
		sys_err("%s", e.what());
		return false;
	}
}

bool Blend_Item_find(const uint32_t item)
{
	return container.HasMember(std::to_string(item).c_str());
}

void Blend_Item_set_value(const LPITEM item)
{
	if (!item)
		return;

	const std::string itemStr = std::to_string(item->GetVnum());
	if (!container.HasMember(itemStr.c_str()))
		return;

	const rapidjson::Value& result = container[itemStr.c_str()];

	if (result.HasMember("type"))
	{
		const auto& type = result["type"];
		if (type.IsInt())
		{
			item->SetSocket(0, type.GetInt());
		}
		else if (type.IsString())
		{
			item->SetSocket(0, FN_get_apply_type(type.GetString()));
		}
	}

	if (result.HasMember("value"))
	{
		const auto& value = result["value"];
		if (value.IsArray())
		{
			int index = number(0, value.Size() - 1);
			item->SetSocket(1, value[index].GetInt());
		}
		else if (value.IsInt())
		{
			item->SetSocket(1, value.GetInt());
		}
	}

	if (result.HasMember("duration"))
	{
		const auto& duration = result["duration"];
		if (duration.IsArray())
		{
			int index = number(0, duration.Size() - 1);
			item->SetSocket(2, duration[index].GetInt());
		}
		else if (duration.IsInt())
		{
			item->SetSocket(2, duration.GetInt());
		}
	}
}

 

blend_item.h
  Reveal hidden contents
#pragma once

#include "item.h"
#include <cstdint>

bool Blend_Item_init();
bool Blend_Item_find(uint32_t item);
void Blend_Item_set_value(LPITEM item);

 

cmd_gm.cpp
  Reveal hidden contents
#include "blend_item.h"

case 'b':
	if (Blend_Item_init())
		ch->ChatPacket(CHAT_TYPE_INFO, "<Blend> Reloaded!");
	else
		ch->ChatPacket(CHAT_TYPE_INFO, "Error Reloading <Blend>!");
	break;

 

 

obsolete rapidjson from 2016...

AND if you seriously want fast parsing, use simdjson

Edited by Thorek
Link to comment
https://metin2.dev/topic/30483-blenditem-refactored/#findComment-167750
Share on other sites

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.