Skip to content

remove seek from NetworkMessage - #4891

Open
xyron98 wants to merge 1 commit into
otland:masterfrom
xyron98:removeseek
Open

remove seek from NetworkMessage#4891
xyron98 wants to merge 1 commit into
otland:masterfrom
xyron98:removeseek

Conversation

@xyron98

@xyron98 xyron98 commented Feb 2, 2025

Copy link
Copy Markdown

Pull Request Prelude

Changes Proposed

Remove seek functionality from NetworkMessage since it is not used anywhere in the codebase and can behave unexpectedly when used with addByte.

Issues addressed:

#4877

How to test:

Compile and run the server.

@ArturKnopik

Copy link
Copy Markdown
Contributor

probably

bool setBufferPosition(MsgSize_t pos)
also can be removed, needs to be checked

@ArturKnopik ArturKnopik linked an issue Feb 3, 2025 that may be closed by this pull request
4 tasks
@MillhioreBT

Copy link
Copy Markdown
Contributor

While it is true that the base does not use seek, you cannot be certain that someone else might use it. It is unsafe if used incorrectly, just like countless other things.

@MillhioreBT
MillhioreBT requested a review from ranisalt February 4, 2025 21:15
@ranisalt

Copy link
Copy Markdown
Member

If seek is not used, tell is likely not used too

@Codinablack

Codinablack commented Feb 11, 2025

Copy link
Copy Markdown
Contributor

So the point is to just remove lua API from the end users because its not used in the datapack?

@MillhioreBT

Copy link
Copy Markdown
Contributor

So the point is to just remove lua API from the end users is its not used in the datapack?

I thought that, in that case we must eliminate 50% of the LUA functions/methods that are not used in the Datapack
modalwindow, helper, event_helper, compat.lua, ect...

@MillhioreBT
MillhioreBT requested a review from nekiro February 11, 2025 04:45
@ArturKnopik

Copy link
Copy Markdown
Contributor

So the point is to just remove lua API from the end users because its not used in the datapack?

So the point is to just remove lua API from the end users is its not used in the datapack?

I thought that, in that case we must eliminate 50% of the LUA functions/methods that are not used in the Datapack modalwindow, helper, event_helper, compat.lua, ect...

please read issue linked in this PR, i hope you will understand why this PR exist

@MillhioreBT

Copy link
Copy Markdown
Contributor

So the point is to just remove lua API from the end users because its not used in the datapack?

So the point is to just remove lua API from the end users is its not used in the datapack?

I thought that, in that case we must eliminate 50% of the LUA functions/methods that are not used in the Datapack modalwindow, helper, event_helper, compat.lua, ect...

please read issue linked in this PR, i hope you will understand why this PR exist

Wouldn't it be better to add a check? Only increase if necessary.
I've been running some tests, and the time difference is negligible in Release mode.

Figure_1

Test Code
#include <benchmark/benchmark.h>
#include <cstring>
#include <type_traits>
#include <vector>

struct BufferInfo
{
	std::vector<char> buffer;
	size_t position = 0;
	size_t length = 0;
};

template <typename T>
void add_with_check(BufferInfo& info, T value)
{
	static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");

	if (info.position + sizeof(T) > info.buffer.size()) {
		return;
	}

	if (info.position + sizeof(T) > info.length) {
		info.length = info.position + sizeof(T);
	}

	std::memcpy(info.buffer.data() + info.position, &value, sizeof(T));
	info.position += sizeof(T);
}

template <typename T>
void add_without_check(BufferInfo& info, T value)
{
	static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");

	if (info.position + sizeof(T) > info.buffer.size()) {
		return;
	}

	std::memcpy(info.buffer.data() + info.position, &value, sizeof(T));
	info.position += sizeof(T);
	info.length += sizeof(T);
}

static void BM_AddWithCheck(benchmark::State& state)
{
	BufferInfo info;
	info.buffer.resize(1024 * 1024);
	int value = 42;

	for (auto _ : state) {
		add_with_check(info, value);
		info.position = 0;
	}
}
BENCHMARK(BM_AddWithCheck);

static void BM_AddWithoutCheck(benchmark::State& state)
{
	BufferInfo info;
	info.buffer.resize(1024 * 1024);
	int value = 42;

	for (auto _ : state) {
		add_without_check(info, value);
		info.position = 0;
	}
}
BENCHMARK(BM_AddWithoutCheck);

static void BM_AddWithCheckOverwrite(benchmark::State& state)
{
	BufferInfo info;
	info.buffer.resize(1024 * 1024);
	info.length = 512 * 1024;
	int value = 42;

	for (auto _ : state) {
		add_with_check(info, value);
		info.position = 0;
	}
}
BENCHMARK(BM_AddWithCheckOverwrite);

static void BM_AddWithoutCheckOverwrite(benchmark::State& state)
{
	BufferInfo info;
	info.buffer.resize(1024 * 1024);
	info.length = 512 * 1024;
	int value = 42;

	for (auto _ : state) {
		add_without_check(info, value);
		info.position = 0;
	}
}
BENCHMARK(BM_AddWithoutCheckOverwrite);

BENCHMARK_MAIN();

Honestly, scenarios where add<T> is called hundreds of thousands of times consecutively seem like something that never happens. And if they did occur, the overhead would be a couple of nanoseconds.

@ArturKnopik

Copy link
Copy Markdown
Contributor

the increase is at 30-35% and this code is commonly used almost everywhere, I prefer not to add checks, it's too big increase in execution time...
everything that happens almost always triggers sending some networkmessages:

  • movement (player rotation, sending of map + possibly a monster if present),
  • magic effect,
  • distance effect,
  • messages to player/channels
  • market
  • from latest protocol preys/bestiary/boostiary (timeout is updated by server)
  • exp/mana spend/skills
  • moving items
  • etc...

@ranisalt

ranisalt commented Jun 25, 2025

Copy link
Copy Markdown
Member

This is a very hot code path and I'd rather not add the check. If not even the engine needs to arbitrarily navigate a network message, I don't think the end user needs to.

seek is not needed, tell is not needed either (it will always equal len), and NetworkMessage::setBufferPosition in C++ will be unused too.

@NRH-AA

NRH-AA commented Jun 26, 2025

Copy link
Copy Markdown

I vote we add: byteAppend(seekPos) stringAppend(seekPos) and they handle the seek, check and add the data, and go back to end. Features above all.

@alysonjacomin

Copy link
Copy Markdown
Contributor

@NRH-AA I completely agree, the more resources the better, and your idea is great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: NetworkMessage always increase size even when it's not needed

7 participants