Jump to content

Player Block System


Recommended Posts

A fool came and gave you no peace and you blocked this fool. Let's see what will happen.

Spoiler

* cannot send group invitations to each other.
* If you have a profile viewing system, both parties cannot send requests to each other.
* cannot send swap requests to each other.
* cannot send guild invitations to each other.
* cannot send PMs to each other.
* In normal chat, what both parties write is not visible to each other.
* The shouts of both sides are invisible to each other.
* If the person you blocked is your friend, the friendships of both parties will be deleted.

additional: while coding the system i fixed a few errors related to mesenge_manager and made adjustments and p2p works. -> You can block or delete a player from the list by typing the player's name from the Messenger panel. There is also a block button inside the target buttons.

.png

 

M2 Download Center

This is the hidden content, please

This is the hidden content, please

  • Metin2 Dev 35
  • Good 4
  • Love 3
  • Love 12
Link to comment
Share on other sites

  • Active+ Member

I extracted a similar systems from different files, including OWSAP's and TRINITY's, but those had issues with p2p features:

1. If you are on CH1, and tagret is on CH99 you can't block that person.

2. If PLAYER1 blocked PLAYER2 and one of them goes on CH99, if PLAYER1 messages PLAYER2 he appears as offline.

 

Did you fix these?

  • Lmao 1

spacer.png

Link to comment
Share on other sites

3 hours ago, SCOOB said:

I extracted a similar systems from different files, including OWSAP's and TRINITY's, but those had issues with p2p features:

1. If you are on CH1, and tagret is on CH99 you can't block that person.

2. If PLAYER1 blocked PLAYER2 and one of them goes on CH99, if PLAYER1 messages PLAYER2 he appears as offline.

 

Did you fix these?

yes dude, There is no problem with p2p. I don't know if this type of system exists in other files, but I am the owner of this system and I shared it today, you have no chance of buying it from anywhere else, and I did not sell it to anyone 

Since I used this system in my game with approximately 1K active players, you can use it comfortably 🙂

.png

 

There are 2468 queries available

Link to comment
Share on other sites

Hey!

Thanks for sharing.

Why store in database player name and not foreign keys on player IDs? As these are direct queries it could made them lighter a little no? There may be a constraint that I don't understand.

This can even be problematic for servers where you can change your player name.

 

 

Edited by Takuma
  • Love 1
  • Love 3
Link to comment
Share on other sites

16 hours ago, Takuma said:

Hey!

Thanks for sharing.

Why store in database player name and not foreign keys on player IDs? As these are direct queries it could made them lighter a little no? There may be a constraint that I don't understand.

This can even be problematic for servers where you can change your player name.

 

 

Hey dude <3, 

While coding the system, I was coding it with id but

.png

When I started coding the block list, it occurred to me that not every player I blocked would always be in the game.

Now let's come to the scenarios I would experience if I coded with id.

* I send the list packet when the player teleports. If the blocked player is not in the game, I cannot write their name there. However, if I only saved the id in memory and saved the player's name along with the id in the database, then I would send the packet of the list by pulling it from the database, not from memory. But I didn't want to use the database every time a player teleported. Additionally, if you change a player name, I will need to correct it in the database.

* If a player I want to unblock is not in the game, I will have to query the player table with the player's name in the database and get his id

In short, I did not use id because I wanted to minimize database usage. Can it be used? Yes, it can be used, but with 2-3 database queries.

When I write systems, I always write them in a way that high-player games can use and I think very carefully. That's why it made more sense to me to code it this way, so I preferred to code it with names.

I don't use name changing in my own active game, so I didn't feel the need to do it. But if you use it, just do this 🙂

// Open player_block.h
// Search:

	auto DeletePlayerBlock(const std::string &strBlockingPlayerName, const std::string &strBlockedPlayerName) -> void;

// Add below:

	auto ChangeName(const std::string &strOldName, const std::string &strNewName) -> void;

// Open player_block.cpp
// Search:

auto CPlayerBlock::DeletePlayerBlock(const std::string &strBlockingPlayerName, const std::string &strBlockedPlayerName) -> void
{
	DBManager::Instance().DirectQuery("DELETE FROM player.player_block_list WHERE blockingplayername = '%s' AND blockedplayername = '%s'", strBlockingPlayerName.c_str(), strBlockedPlayerName.c_str());
}

// Add below:

auto CPlayerBlock::ChangeName(const std::string &strOldName, const std::string &strNewName) -> void
{
	auto it = m_map_PlayerBlock.find(strOldName);
	if (it != m_map_PlayerBlock.end())
	{
		m_map_PlayerBlock[strNewName] = std::move(it->second);
		m_map_PlayerBlock.erase(it);
	}

	for (auto &it : m_map_PlayerBlock)
	{
		auto it2 = it.second.find(strOldName);
		if (it2 != it.second.end())
		{
			it.second.erase(it2);
			it.second.emplace(strNewName);
		}
	}

	DBManager::Instance().DirectQuery("UPDATE player.player_block_list SET blockingplayername = '%s' WHERE blockingplayername = '%s'", strNewName.c_str(), strOldName.c_str());
	DBManager::Instance().DirectQuery("UPDATE player.player_block_list SET blockedplayername = '%s' WHERE blockedplayername = '%s'", strNewName.c_str(), strOldName.c_str());

	sys_log(0, "PLAYER_BLOCK: ChangeName: %s -> %s", strOldName.c_str(), strNewName.c_str());
}

// Open questlua_pc.cpp

// Add includes:

#ifdef ENABLE_PLAYER_BLOCK_SYSTEM
#include "player_block.h"
#endif

// Search:

		/* delete messenger list */
		MessengerManager::instance().RemoveAllList(ch->GetName());

// Add below:

#ifdef ENABLE_PLAYER_BLOCK_SYSTEM
		/* player block list */
		CPlayerBlock::Instance().ChangeName(ch->GetName(), szName);
#endif
Edited by Kio
  • Good 1
Link to comment
Share on other sites

1 hour ago, Kio said:

Hey dude <3, 

While coding the system, I was coding it with id but

.png

When I started coding the block list, it occurred to me that not every player I blocked would always be in the game.

Now let's come to the scenarios I would experience if I coded with id.

* I send the list packet when the player teleports. If the blocked player is not in the game, I cannot write their name there. However, if I only saved the id in memory and saved the player's name along with the id in the database, then I would send the packet of the list by pulling it from the database, not from memory. But I didn't want to use the database every time a player teleported. Additionally, if you change a player name, I will need to correct it in the database.

* If a player I want to unblock is not in the game, I will have to query the player table with the player's name in the database and get his id

In short, I did not use id because I wanted to minimize database usage. Can it be used? Yes, it can be used, but with 2-3 database queries.

When I write systems, I always write them in a way that high-player games can use and I think very carefully. That's why it made more sense to me to code it this way, so I preferred to code it with names.

I don't use name changing in my own active game, so I didn't feel the need to do it. But if you use it, just do this 🙂

// Open player_block.h
// Search:

	auto DeletePlayerBlock(const std::string &strBlockingPlayerName, const std::string &strBlockedPlayerName) -> void;

// Add below:

	auto ChangeName(const std::string &strOldName, const std::string &strNewName) -> void;

// Open player_block.cpp
// Search:

auto CPlayerBlock::DeletePlayerBlock(const std::string &strBlockingPlayerName, const std::string &strBlockedPlayerName) -> void
{
	DBManager::Instance().DirectQuery("DELETE FROM player.player_block_list WHERE blockingplayername = '%s' AND blockedplayername = '%s'", strBlockingPlayerName.c_str(), strBlockedPlayerName.c_str());
}

// Add below:

auto CPlayerBlock::ChangeName(const std::string &strOldName, const std::string &strNewName) -> void
{
	auto it = m_map_PlayerBlock.find(strOldName);
	if (it != m_map_PlayerBlock.end())
	{
		m_map_PlayerBlock[strNewName] = std::move(it->second);
		m_map_PlayerBlock.erase(it);
	}

	for (auto &it : m_map_PlayerBlock)
	{
		auto it2 = it.second.find(strOldName);
		if (it2 != it.second.end())
		{
			it.second.erase(it2);
			it.second.emplace(strNewName);
		}
	}

	DBManager::Instance().DirectQuery("UPDATE player.player_block_list SET blockingplayername = '%s' WHERE blockingplayername = '%s'", strNewName.c_str(), strOldName.c_str());
	DBManager::Instance().DirectQuery("UPDATE player.player_block_list SET blockedplayername = '%s' WHERE blockedplayername = '%s'", strNewName.c_str(), strOldName.c_str());

	sys_log(0, "PLAYER_BLOCK: ChangeName: %s -> %s", strOldName.c_str(), strNewName.c_str());
}

// Open questlua_pc.cpp

// Add includes:

#ifdef ENABLE_PLAYER_BLOCK_SYSTEM
#include "player_block.h"
#endif

// Search:

		/* delete messenger list */
		MessengerManager::instance().RemoveAllList(ch->GetName());

// Add below:

#ifdef ENABLE_PLAYER_BLOCK_SYSTEM
		/* player block list */
		CPlayerBlock::Instance().ChangeName(ch->GetName(), szName);
#endif

Actually, I don't understand the problem. You can store the id very well, but still ask your DBMS to return the player name to you without creating new queries. This takes up less space, it ensures that you don't keep data that doesn't correspond to anything, etc.

Gurgarath told me that friends management was a real disaster. And I think we don't have to start again on this bad basis. You can keep your internal operation with loading the nicknames into memory (for displaying the list), but store the IDs in the database. You just need to change your queries (not adding new queries) to support it

 

 

 

 

Link to comment
Share on other sites

19 minutes ago, Takuma said:

Actually, I don't understand the problem. You can store the id very well, but still ask your DBMS to return the player name to you without creating new queries. This takes up less space, it ensures that you don't keep data that doesn't correspond to anything, etc.

Gurgarath told me that friends management was a real disaster. And I think we don't have to start again on this bad basis. You can keep your internal operation with loading the nicknames into memory (for displaying the list), but store the IDs in the database. You just need to change your queries (not adding new queries) to support it

 

 

 

 

Yes, the messenger manager system is a complete disgrace. Because a database query is made with every teleportation. and there are many other nonsense topics. If we use the player ID, you will still have to send a database query every time you teleport. Because imagine a player on the disabled list leaves the game. But you need to write the player's name on that list, you cannot do this with the id because it is not in the game. You will need to pull it with a database query. The reason why I don't use id is to avoid making database queries for every player in every teleport.

Link to comment
Share on other sites

5 hours ago, Kio said:

Yes, the messenger manager system is a complete disgrace. Because a database query is made with every teleportation. and there are many other nonsense topics. If we use the player ID, you will still have to send a database query every time you teleport. Because imagine a player on the disabled list leaves the game. But you need to write the player's name on that list, you cannot do this with the id because it is not in the game. You will need to pull it with a database query. The reason why I don't use id is to avoid making database queries for every player in every teleport.

Actually,  what I was saying is that you can do all the queries with the player name at the source level and your DBMS will store IDs for it. You just have to adapt a little bit the queries in your player_block.cpp.

Example to insert new line in the  player_block_list table : 

INSERT INTO player_bloc_list (id1, id2)
SELECT p1.id, p2.id
FROM player p1
JOIN player p2 ON p1.name = 'Kio' AND p2.name = 'Takuma';

Same way for select etc..

By doing this, indeed, you add an additional join during insertion (though considering the capabilities of the DBMS compared to the current Metin2 servers, it may be negligible). However, on the other hand, storing IDs is easier, and it aligns a bit more with standards.

Link to comment
Share on other sites

11 minutes ago, Takuma said:

Actually,  what I was saying is that you can do all the queries with the player name at the source level and your DBMS will store IDs for it. You just have to adapt a little bit the queries in your player_block.cpp.

Example to insert new line in the  player_block_list table : 

INSERT INTO player_bloc_list (id1, id2)
SELECT p1.id, p2.id
FROM player p1
JOIN player p2 ON p1.name = 'Kio' AND p2.name = 'Takuma';

Same way for select etc..

By doing this, indeed, you add an additional join during insertion (though considering the capabilities of the DBMS compared to the current Metin2 servers, it may be negligible). However, on the other hand, storing IDs is easier, and it aligns a bit more with standards.

Dude, I told you it could be done with id, but I said it has to be a SQL query? I don't understand what else you are explaining. I have already explained what you said in my two previous comments.

.png

Imagine there are a lot of player blocks in a high player game and since you use ID for each teleport, are you doing this loading using the database?

Either you haven't studied the system well, that's why you can't understand what I'm saying, or you're giving a different answer to what I'm telling you, I don't understand.

Anyway, that's what made sense to me, so I wrote it that way. If it doesn't make sense to you, the system is open to development 🙂 You can take the ID and upload it with the database. Have a nice use 🙂

  • kekw 2
  • Eyes 2
Link to comment
Share on other sites

  • Active+ Member

I still think that a python side block system is more suitable for this game, only for messenger.

 

I made a simple python system that stores the blocked players name in a txt file.

 

Video: https://metin2.download/video/3BZHBKUI32A5acnqXdpwKu878jJdP91T/.mp4

Edited by Metin2 Dev International
Core X - External 2 Internal

spacer.png

Link to comment
Share on other sites

On 12/6/2023 at 11:12 PM, SCOOB said:

I still think that a python side block system is more suitable for this game, only for messenger.

 

I made a simple python system that stores the blocked players name in a txt file.

 

Video: https://metin2.download/video/3BZHBKUI32A5acnqXdpwKu878jJdP91T/.mp4

The video has been deleted so I can't see it, but as far as I understand from your message, you imported the list into Python. Do you think I didn't think about this? 😄 What will you do when the player deletes and installs the game? 👀 🧌🚎

Link to comment
Share on other sites

  • Active+ Member
10 hours ago, Kio said:

The video has been deleted so I can't see it, but as far as I understand from your message, you imported the list into Python. Do you think I didn't think about this? 😄 What will you do when the player deletes and installs the game? 👀 🧌🚎

Well, You can always create a registry file like some login interfaces do. And even  if you uninstall and reinstall the game, the file is still there unless you delete it.

But that's an extreme situation, most players don't care about that. They care about getting rid of an annoying person.

Your system has some vulnerabilities unfortunately.. 

 

Example:

import _winreg
REG_PATH = r"SOFTWARE\test"

 

def set_reg(name, value):
    try:
        _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, REG_PATH)
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0, _winreg.KEY_WRITE)
        _winreg.SetValueEx(registry_key, name, 0, _winreg.REG_SZ, value)
        _winreg.CloseKey(registry_key)
        return True
    except WindowsError:
        return False

def get_reg(name):
    try:
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0, _winreg.KEY_READ)
        value, regtype = _winreg.QueryValueEx(registry_key, name)
        _winreg.CloseKey(registry_key)
        return str(value)
    except WindowsError:
        return None  

     

 

Edited by SCOOB

spacer.png

Link to comment
Share on other sites

10 hours ago, Jira said:

This is the hidden content, please

This is the hidden content, please

This is the hidden content, please

ez sql inject xd

HAHAHAHA 😄 

.png

You cannot unblock a player you have not blocked. Are you so blind that you can't see the control at the top? xD Tell me what you use, I'm curious about its head :kekw:

2 hours ago, SCOOB said:

Well, You can always create a registry file like some login interfaces do. And even  if you uninstall and reinstall the game, the file is still there unless you delete it.

But that's an extreme situation, most players don't care about that. They care about getting rid of an annoying person.

Your system has some vulnerabilities unfortunately.. 

 

Example:

import _winreg
REG_PATH = r"SOFTWARE\test"

 

def set_reg(name, value):
    try:
        _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, REG_PATH)
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0, _winreg.KEY_WRITE)
        _winreg.SetValueEx(registry_key, name, 0, _winreg.REG_SZ, value)
        _winreg.CloseKey(registry_key)
        return True
    except WindowsError:
        return False

def get_reg(name):
    try:
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0, _winreg.KEY_READ)
        value, regtype = _winreg.QueryValueEx(registry_key, name)
        _winreg.CloseKey(registry_key)
        return str(value)
    except WindowsError:
        return None  

     

 

It makes sense to use this for account registration, but the player can enter the game from another computer or format his computer, there are many more possibilities like this. Your opinion is very amateur.

Edited by Kio
  • Metin2 Dev 1
  • kekw 1
  • Good 1
Link to comment
Share on other sites

  • Active+ Member
13 minutes ago, Kio said:

HAHAHAHA 😄 

.png

You cannot unblock a player you have not blocked. Are you so blind that you can't see the control at the top? xD Tell me what you use, I'm curious about its head 😄

It makes sense to use this for account registration, but the player can enter the game from another computer or format his computer, there are many more possibilities like this. Your opinion is very amateur.

Don't get so triggered man, breathe a little. These are constructive arguments. What normal player plays from 3 computers ? Even so, it's not that hard to block the person that annoys you again. It's not a game breaking issue. 

I know for a fact that the C++ system has vulnerabilities, even Trinity and Owsap had this system in their previous files but uninstalled them. And they did that for a reason.

Edited by SCOOB

spacer.png

Link to comment
Share on other sites

4 minutes ago, SCOOB said:

Don't get so triggered man, breathe a little. These are constructive arguments. What normal player plays from 3 computers ? Even so, it's not that hard to block the person that annoys you again. It's not a game breaking issue. 

I know for a fact that the C++ system has vulnerabilities, even Trinity and Owsap had this system in their previous files but uninstalled them. And they did that for a reason.

Dude, don't I own the system? OWSAP OR SOMEONE ELSE? Do you write your systems with this mindset? Ah, it will be blocked again, no problem  😄 You say there is a security vulnerability, can you tell me about the security vulnerability with your vast knowledge?

Link to comment
Share on other sites

  • Active+ Member
2 minutes ago, TAUMP said:

Trash community only hatefull if someone posted normal system which are be used by players. Instead someone tell problem in code, they will hate code about sql inject, security backdoors and etc. This is reason why is nothing free.

Do you live in communism? Can't we tell our opinion or what? If someone has a different opinion it does not mean that person is trash. 

Stop being so brainwashed by modern society.

spacer.png

Link to comment
Share on other sites

7 minutes ago, TAUMP said:

Trash community only hatefull if someone posted normal system which are be used by players. Instead someone tell problem in code, they will hate code about sql inject, security backdoors and etc. This is reason why is nothing free.

The strange thing is that neither SQL Inject nor any security vulnerabilities exist. In order for SQL to be injected, SQL code must be present in the player's name, which is not possible anyway. To block a player, the player must be in the game. Someone can't block or unblock a name just because they want to, they have to be a real gamer. These smart friends of ours think that we didn't think about these things while writing the system 🙂 It's strange that people can't digest it when someone does good deeds. But it doesn't matter, I laugh and have fun while answering these questions, it adds action to my life 🏇

  • Lmao 1
Link to comment
Share on other sites

  • Premium
1 minute ago, SCOOB said:

Do you live in communism? Can't we tell our opinion or what? If someone has a different opinion it does not mean that person is trash. 

Stop being so brainwashed by modern society.

Such opinions are useless, why doesn't he just say the remedy? No, he would rather write that there is SQL inject, there is a backdoor, there is Putin's code. That's why this community sucks and no one wants to contribute anything anymore.

Just now, Kio said:

The strange thing is that neither SQL Inject nor any security vulnerabilities exist. In order for SQL to be injected, SQL code must be present in the player's name, which is not possible anyway. To block a player, the player must be in the game. Someone can't block or unblock a name just because they want to, they have to be a real gamer. These smart friends of ours think that we didn't think about these things while writing the system 🙂 It's strange that people can't digest it when someone does good deeds. But it doesn't matter, I laugh and have fun while answering these questions, it adds action to my life 🏇

I'll give you a piece of advice, don't share anything, get paid for it.

  • Smile Tear 1


 

Link to comment
Share on other sites

8 minutes ago, SCOOB said:

Do you live in communism? Can't we tell our opinion or what? If someone has a different opinion it does not mean that person is trash. 

Stop being so brainwashed by modern society.

You don't express any opinion. You say there is a vulnerability in the system. This is not expressing an opinion. Since you know so much that there is a security vulnerability, you need to stand behind your words and show me this with your vast knowledge. Yes, this is a community and people come in and look at this issue. Instead of creating a question mark in people's minds due to your unfounded claims, prove your claims or do not make empty comments :default_ph34r:

Link to comment
Share on other sites

  • Honorable Member
1 hour ago, TAUMP said:

Trash community only hatefull if someone posted normal system which are be used by players. Instead someone tell problem in code, they will hate code about sql inject, security backdoors and etc. This is reason why is nothing free.

He is turkish + he uses cat profile photo + he gets bad comments due to free releases: New Mali???

  • Lmao 5

 

Link to comment
Share on other sites

  • 1 month later...
  • Active+ Member

@KioI wanted to apologize for my undocumented comments above.

I installed the system today and everything seems to be working good.

I had some bad experiences with a similar system in the past, but this one is stable.

Great job and thank you for the release!:default_cool:

  • muscle 1
  • Love 1

spacer.png

Link to comment
Share on other sites

Announcements



×
×
  • 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.