Jump to content

Round Trip Time (RTT) Ping Statistics


Recommended Posts

  • Honorable Member

M2 Download Center

This is the hidden content, please
  ( GitHub )
This is the hidden content, please
 
( MEGA )
This is the hidden content, please
 
( Internal )

Hey M2Dev, here is a little statistics overview of the Round Trip Time (RTT) Ping and Packet Loss.

Usefully for some, useless for others, so I decided to share it.

Preview

240109Preview.png

The image is an example...
The results where not captured accurately because they kept updating while I tried to take screenshots.
You will not get any PING on localhost.

 

If you find any problems let me know.

Edited by Owsap
Links & Repository Updated.
  • Metin2 Dev 131
  • Eyes 2
  • Not Good 2
  • Cry 1
  • Think 4
  • Confused 1
  • Scream 1
  • Good 27
  • Love 3
  • Love 73
Link to comment
Share on other sites

41 minutes ago, luqurote said:

please share fix

In ServerStateChecker.cpp file, end of CServerStateChecker::GetEchoReply function:

 Replace the following:

return;

with it:

free(ReplyBuffer);

 

Edit:

Or you can use fixed static variable as buffer, that is should be better in this case. 

Edited by UdvAtt108

All wolves are gray in the dark.

Link to comment
Share on other sites

I have this sysser:

0724 13:48:16827 :: UISCRIPT_LOAD_ERROR: can only concatenate tuple (not "list") to tuple [filename UIScript/MiniMap.py]
0724 13:48:16829 :: 
uiMiniMap.py(line:341) __LoadWindow
ui.py(line:3740) GetChild

MiniMap.LoadWindow.Bind - <type 'exceptions.KeyError'>:'RTTTextLine'

 

Link to comment
Share on other sites

  • Honorable Member
12 hours ago, UdvAtt108 said:

There is a nice memory leak, that spammed in every 5 seconds and makes high memory usage few hours later... 

Please, be carefull when you use memory allocations... 

Easy to fix it, lets correct it. 

Glad someone had to point that out, obviously, every allocation must be freed after using it but I wasn’t sure if IcmpSendEcho2 function cleared it for me, but honestly, I forgot about it.
Since you had good eyes in pointing that out, you also forgot to mention to close the IcmpFile HANDLE.

7 hours ago, Jimmermania said:

I have this sysser:

0724 13:48:16827 :: UISCRIPT_LOAD_ERROR: can only concatenate tuple (not "list") to tuple [filename UIScript/MiniMap.py]
0724 13:48:16829 :: 
uiMiniMap.py(line:341) __LoadWindow
ui.py(line:3740) GetChild

MiniMap.LoadWindow.Bind - <type 'exceptions.KeyError'>:'RTTTextLine'

 

The file in the tutorial "UIScript/MiniMap.py" already contains the correct structure to attach more children in the window. If you didn't use the file you can do this (2 options);

Spoiler
''' 1. @ UIScript/MiniMap.py '''
# Search all
	"children" :
	(
		...
	),

# Replace with
	"children" :
	[
		...
	],

 

Or you can just add;

Spoiler
''' 1. @ UIScript/MiniMap.py '''
# Search
				## ServerInfo
				{
					"name" : "ServerInfo",
					"type" : "text",

					"text_horizontal_align" : "center",

					"outline" : 1,

					"x" : 70,
					"y" : 140,

					"text" : "",
				},

# Add below
				## RTT Statistics
				{
					"name" : "RTTTextLine",
					"type" : "text",

					"x" : 0,
					"y" : 160,

					"horizontal_align" : "center",
					"text_horizontal_align" : "center",

					"text" : "",
					"outline" : 1,
				},
				{
					"name" : "PacketLossTextLine",
					"type" : "text",

					"x" : 0,
					"y" : 160 + 15,

					"horizontal_align" : "center",
					"text_horizontal_align" : "center",

					"text" : "",
					"outline" : 1,
				},

 


Links & Repository Updated.

Edited by Owsap
  • Good 2
  • Love 1
Link to comment
Share on other sites

  • 4 weeks later...
  • 4 weeks later...
  • Management

First of all, thank you for this release.

Since I use a hostname instead of an IP, this didn't work for me, this are the changes I made to make it work (also works with IP).

	CAccountConnector& rkAccountConnector = CAccountConnector::Instance();

	struct hostent* remoteHost;

	if ((remoteHost = gethostbyname(rkAccountConnector.GetServerAddr())) == NULL) {
#if defined(_DEBUG_RTT)
		TraceError("Unknown Hostname.\n\n");
#endif
		return; // Unkown Hostname
	}

	char* pDmsIP = inet_ntoa(*(struct in_addr*)(remoteHost->h_addr_list[0]));
	ipaddr = inet_addr(pDmsIP);

 

Edited by Karbust
  • Good 1

raw

raw

Link to comment
Share on other sites

  • Honorable Member
28 minutes ago, Karbust said:

First of all, thank you for this release.

Since I use a hostname instead of an IP, this didn't work for me, this are the changes I made to make it work (also works with IP).

	CAccountConnector& rkAccountConnector = CAccountConnector::Instance();

	struct hostent* remoteHost;

	if ((remoteHost = gethostbyname(rkAccountConnector.GetServerAddr())) == NULL) {
#if defined(_DEBUG_RTT)
		TraceError("Unknown Hostname.\n\n");
#endif
		return; // Unkown Hostname
	}

	char* pDmsIP = inet_ntoa(*(struct in_addr*)(remoteHost->h_addr_list[0]));
	ipaddr = inet_addr(pDmsIP);

 

Thanks for contributing, I will update the repository soon.

Link to comment
Share on other sites

  • 3 months later...
  • Management

Since not everyone has a good internet and there are instances when someone can have high ping, I think it shouldn't affect the game play capability in such cases, so I just added the ping code to a thread and now it doesn't block the game.

This is the hidden content, please

 

 

Edited by Karbust
  • Metin2 Dev 48
  • Good 8
  • Love 2
  • Love 13

raw

raw

Link to comment
Share on other sites

  • 6 months later...
  • 2 months later...
On 9/11/2021 at 7:46 PM, Karbust said:

First of all, thank you for this release.

Since I use a hostname instead of an IP, this didn't work for me, this are the changes I made to make it work (also works with IP).

	CAccountConnector& rkAccountConnector = CAccountConnector::Instance();

	struct hostent* remoteHost;

	if ((remoteHost = gethostbyname(rkAccountConnector.GetServerAddr())) == NULL) {
#if defined(_DEBUG_RTT)
		TraceError("Unknown Hostname.\n\n");
#endif
		return; // Unkown Hostname
	}

	char* pDmsIP = inet_ntoa(*(struct in_addr*)(remoteHost->h_addr_list[0]));
	ipaddr = inet_addr(pDmsIP);

 

Hi all, since my good friend @ Karbust forgot to mention (this mod work well btw and ty both), I've come to let you my small contribution, explaining how to implement.

His mod is done like this:

After implemented the full mod as @ Owsap explain, open the file
Client source -> in file ServerStateChecker.cpp

Search for:

ipaddr = inet_addr(strcmp(rkAccountConnector.GetServerAddr(), "localhost") == 0 ? "127.0.0.1" : rkAccountConnector.GetServerAddr());

 

and replace that* line (just that one) with all these given by @ Karbust :

	struct hostent* remoteHost;
	if ((remoteHost = gethostbyname(rkAccountConnector.GetServerAddr())) == NULL) {
#if defined(_DEBUG_RTT)
		TraceError("Unknown Hostname.\n\n");
#endif
		return; // Unkown Hostname
	}
	char* pDmsIP = inet_ntoa(*(struct in_addr*)(remoteHost->h_addr_list[0]));
	ipaddr = inet_addr(pDmsIP);


Work just fine for me.

EDIT: @Jimmermania you must have missed a step somewhere, verify again, or rollback to a previous backup and restart again.

Edited by davecosmo
  • Metin2 Dev 1
  • Love 1
Link to comment
Share on other sites

  • 7 months later...
  • 3 months later...
  • Premium

Tested and is working.
If you get the error with thread on compilation just add std::thread like in this example:

#if defined(ENABLE_PERFORMANCE_STATISTICS)
	static DWORD s_dwCheckPingTime = ELTimer_GetMSec();

	if (ELTimer_GetMSec() - s_dwCheckPingTime > CServerStateChecker::MAX_RTT_REQUEST_MS)
	{
		std::thread t(NonBlockingServerStateChecker, &m_kServerStateChecker, &m_dwRTT, &m_fPktLossPct, &s_dwCheckPingTime);
		t.detach();
	}
#endif

Also if the ms is 999ms you need to allow IMCP traffic on your FIREWALL.

And done.
.png

plague.png.1f5de75b42146262dcd655a5a8078

Link to comment
Share on other sites

4 hours ago, DemOnJR said:

Tested and is working.
If you get the error with thread on compilation just add std::thread like in this example:

#if defined(ENABLE_PERFORMANCE_STATISTICS)
	static DWORD s_dwCheckPingTime = ELTimer_GetMSec();

	if (ELTimer_GetMSec() - s_dwCheckPingTime > CServerStateChecker::MAX_RTT_REQUEST_MS)
	{
		std::thread t(NonBlockingServerStateChecker, &m_kServerStateChecker, &m_dwRTT, &m_fPktLossPct, &s_dwCheckPingTime);
		t.detach();
	}
#endif

Also if the ms is 999ms you need to allow IMCP traffic on your FIREWALL.

And done.
.png

How about adding an task with std::async? I would prefer it with a promise like this:

private:
  std::future<int32_t> m_pingTask{};
  int32_t m_ping{}; 
public:
  // easy running in background :_D 
  void Ping()
  {
    // Task is already running
    if (m_pingTask.valid()) return;

    m_pingTask = std::async(std::launch::async, []() { /*... Perform ping request here */ return ping;}); 
  }

  void UpdatePing()
  {
    if (m_pingTask.valid())
    {
      const auto status = m_pingTask.wait_until(std::chrono::system_clock::now() + std::chrono::seconds(0)); // 0 not timeout if the task is done here
      if (status == std::future_status::ready) // ready means the task is done
      {
          m_ping = m_pingTask.get(); // here you can get the like use python create a func for it like app.GetPing() and return this value here
          m_pingTask = {};
      }
    }
  }

   int32_t GetPing() const
   {
		return m_ping;
   }



 

Edited by ZentraX
Link to comment
Share on other sites

  • Premium
Spoiler
16 minutes ago, ZentraX said:

How about adding an task with std::async? I would prefer it with a promise like this:

private:
  std::future<int32_t> m_pingTask{};
  int32_t m_ping{}; 
public:
  // easy running in background :_D 
  void Ping()
  {
    // Task is already running
    if (m_pingTask.valid()) return;

    m_pingTask = std::async(std::launch::async, []() { /*... Perform ping request here */ return ping;}); 
  }

  void UpdatePing()
  {
    if (m_pingTask.valid())
    {
      const auto status = m_pingTask.wait_until(std::chrono::system_clock::now() + std::chrono::seconds(0)); // 0 not timeout if the task is done here
      if (status == std::future_status::ready) // ready means the task is done
      {
          m_ping = m_pingTask.get(); // here you can get the like use python create a func for it like app.GetPing() and return this value here
          m_pingTask = {};
      }
    }
  }

   int32_t GetPing() const
   {
		return m_ping;
   }



 

 

Idk you can try to use async also is your choice, i do not use boost so thread is ok.

plague.png.1f5de75b42146262dcd655a5a8078

Link to comment
Share on other sites

  • 4 months later...
  • 3 weeks later...

Can anyone help me with this syserr error

0117 20:31:09259 :: 
networkModule.py(line:197) SetSelectCharacterPhase
system.py(line:177) __hybrid_import
system.py(line:142) _process_result
introSelect.py(line:28) <module>
system.py(line:177) __hybrid_import
system.py(line:142) _process_result
interfaceModule.py(line:27) <module>
system.py(line:177) __hybrid_import

networkModule.SetSelectCharacterPhase - <type 'exceptions.IndentationError'>:unindent does not match any outer indentation level (uiMiniMap.py, line 395)

0117 20:31:09259 :: ============================================================================================================
0117 20:31:09259 :: Abort!!!!

spacer.png

Edited by Metin2 Dev International
Core X - External 2 Internal
  • kekw 1
  • Facepalm 1
  • Cry 1
Link to comment
Share on other sites

  • 2 weeks later...

I did as you said, but it returned the following error:

Quote

0127 13:40:05685 :: 
Ping statistics for 51.81.90.206:
0127 13:40:05685 ::     Packets: Sent = 1, Received = 1, Lost = 0 (0.00% loss),
0127 13:40:07239 :: 
networkModule.py(line:197) SetSelectCharacterPhase
system.py(line:177) __hybrid_import
system.py(line:142) _process_result
introSelect.py(line:28) <module>
system.py(line:177) __hybrid_import
system.py(line:142) _process_result
interfaceModule.py(line:27) <module>
system.py(line:177) __hybrid_import

networkModule.SetSelectCharacterPhase - <type 'exceptions.SyntaxError'>:invalid syntax (uiMiniMap.py, line 340)

0127 13:40:07239 :: ============================================================================================================
0127 13:40:07239 :: Abort!!!!


 

spacer.png

Edited by Metin2 Dev International
Core X - External 2 Internal
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.