Jump to content

Reason of delay?


Recommended Posts

What would be the reason of pause the tread of player for like 1.5 to 2 seconds upon sendSkillList? 

I did berchmark on the

public void sendSkillList(final L2PcInstance player)

code it return literally 0.06 millisecond respond time So thats no the reason. There is no other code

both admin (give_all_skills) and the sub-class use the sendSkillList(player);  which it really has no delay since i made it's List and it's really fast.

What else would cause this 1.5 - 2 second delay upon give skill list?  Give some advice

Link to comment
Share on other sites

21 minutes ago, .Elfocrash said:

It's client side. The server is bombarding the client with one packet per skill and it essentially gets flooded.

Wait wait.. the skillList is a packet that contains a sub-list so basically  on a List you load all getPlayerAvailableSkills 

and u add them on SkillList packet and then at the end u send 1 time the packet.  so ?  It's not about fix. 1.5 sec delay is no problem is just

it make me so fucking curious.. i did berchmarks and is so fast that even in nanoseconds it show 3500 to complete all giveSkillListToPlayer(); 

Edited by Ο Χάρος
Link to comment
Share on other sites

The method to retrieve skills is probably not optimized. The same effect happens on subclass acquisition, where you can wait a solid 3 to 5 seconds, only because the method doesn't filter correctly things, and reward you will all possible skills (and reward skills means one database query per skill acquisition, because there is no global method to reward all skills), while you should filter first and reward after.

sendSkillList is probably ok and got no specific reason to bug by itself (there was a slight edit to do for a specific case, but otherwise nothing to do).

Before holidays on Croatia, I was actually reworking the whole thing on aCis.

 

You should add more details about which methods you are invoking, what you try to do, etc.

Edited by Tryskell
Link to comment
Share on other sites

19 minutes ago, Tryskell said:

The method to retrieve skills is probably not optimized. The same effect happens on subclass acquisition, where you can wait a solid 3 to 5 seconds, only because the method doesn't filter correctly things, and reward you will all possible skills (and reward skills means one database query per skill acquisition, because there is no global method to reward all skills), while you should filter first and reward after.

sendSkillList is probably ok and got no specific reason to bug by itself (there was a slight edit to do for a specific case, but otherwise nothing to do).

Before holidays on Croatia, I was actually reworking the whole thing on aCis.

 

You should add more details about which methods you are invoking, what you try to do, etc.

EDIT

sendSkillList() is packing the skills together but the restoreSkills() method is locking the shit out of the thread because of the sql involved.

Edited by .Elfocrash
Link to comment
Share on other sites

Let me get the things straight:

This is the admin method that give ALl skills to players.  and the method that does that is the sendSkillList ( same called in sub-class)


	private void adminGiveAllSkills(final L2PcInstance activeChar, final boolean includedByFs)
	{
		final L2Object target = activeChar.getTarget();
		L2PcInstance player = null;
		if (target instanceof L2PcInstance)
		{
			player = (L2PcInstance) target;
		}
		else
		{
			activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.INCORRECT_TARGET));
			return;
		}
		player.sendSkillList();
	}

 

Now in this method as u can see: 

public void sendSkillList(final L2PcInstance player)
	{
		boolean isDisabled = false;
		final SkillList sl = new SkillList();
		
		if (player != null)
		{
			for (final L2Skill s : player.getAllSkills())
			{
				if (s == null)
				{
					continue;
				}
				if (s.getId() > 9000 && s.getId() < 9007)
				{
					continue;
				}
				if (_transformation != null && !containsAllowedTransformSkill(s.getId()) && !s.allowOnTransform())
				{
					continue;
				}
				if (player.getClan() != null)
				{
					isDisabled = s.isClanSkill() && player.getClan().getReputationScore() < 0;
				}
				boolean isEnchantable = SkillTable.getInstance().isEnchantable(s.getId());
				if (isEnchantable)
				{
					final L2EnchantSkillLearn esl = EnchantGroupsTable.getInstance().getSkillEnchantmentBySkillId(s.getId());
					if (esl != null)
					{
						if (s.getLevel() < esl.getBaseLevel())
						{
							isEnchantable = false;
						}
					}
					else
					{
						isEnchantable = false;
					}
				}
				if (getAioEndTime() > System.currentTimeMillis() && !isGM() && !isInsideZone(ZONE_TOWN))
				{
					isDisabled = true;
				}
				sl.addSkill(s.getId(), s.getLevel(), s.isPassive(), isDisabled, isEnchantable);
			}
		}
		
		sendPacket(sl);
	}

 

All skills are gathered into a packet that is send only 1 time upon the end of code. This class takes 3500 nanoseconds to be done, aka 0 milliseconds

 

The only method that retrieve the skills here is just this:

 

public final L2Skill[] getAllSkills()
    {
        if (_skills == null)
        {
            return new L2Skill[0];
        }
        return _skills.values().toArray(new L2Skill[_skills.values().size()]);
    }

Basically a Map that is turned into array (no delay at all obviously). 

 

I did in both methods 

long ms = System.getNanoTime(); 

System.out.println(System.getNanoTime() - ms); and it show all 0 MS in total.  MAX 1 ms. So the reason of 2 sec delay is not justified

Link to comment
Share on other sites

6 minutes ago, .Elfocrash said:

He said the code returns the skills in milliseconds but the client lags. If the method returns data instantly then it is clearly the client.

If it wasn't then every player would lag not just the one.

 

I did compare to H5 branch (cause i use freya) and the code is the same (just in H5 they added 1 more check for add the skill on holders) nothing to do with retreive or store. 

But in H5 it really takes 0.2 sec delay to give 45 skills while in freya it take 1.5 sec delay. I can imagine with extra skills it could take 3 sec delay.

Link to comment
Share on other sites

1 minute ago, Ο Χάρος said:

 

I did compare to H5 branch (cause i use freya) and the code is the same (just in H5 they added 1 more check for add the skill on holders) nothing to do with retreive or store. 

But in H5 it really takes 0.2 sec delay to give 45 skills while in freya it take 1.5 sec delay. I can imagine with extra skills it could take 3 sec delay.

It might come down to the packet length which they might have improved in H5.

Link to comment
Share on other sites

Just now, .Elfocrash said:

It might come down to the packet length which they might have improved in H5.

 

oh, true didn't think of that.  If i do   packet.toString().lenght();  this would return the packet size (somehow) i could compare to H5 then ?

Link to comment
Share on other sites

Just now, .Elfocrash said:

Nah the size should be roughly the same. It is the client code that might process it differently in H5

So basically you say that the size wouldnt change maybe the method that handle the packet is wrong. i check the H5 method SKilLIst and is this https://pastebin.com/AXws0Pgb

while on freya ishttps://pastebin.com/3HzmwR49

So basically on Freya the constructor create a new FastList which is slow as fuck compare to arrayList so ill go ahead and change this cause javolution is slower by 30% as i saw

I'll try my lack with this and report back. 

Link to comment
Share on other sites

Just now, .Elfocrash said:

There is no way that this is the problem.

Another obvious pointer would be that H5 is using HikariCP as the default db connection pool while Freya is still c3p0 which is like a million times slower (if somehow db is getting involved).

Now im thinking it's stupid cause the method was including in berchmark so any sub-calculations wouldnt again be recorded on system out at sendSkillList.. again i tested it nothing changed.. 

You're right..  No there is no DB connection involved.. I double check the code.

 

It goes from this: 

/**
	 * This function will give all the skills that the target can learn at his/her level
	 * @param activeChar: the gm char
	 */
	private void adminGiveAllSkills(final L2PcInstance activeChar, final boolean includedByFs)
	{
		final L2Object target = activeChar.getTarget();
		L2PcInstance player = null;
		if (target instanceof L2PcInstance)
		{
			player = (L2PcInstance) target;
		}
		else
		{
			activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.INCORRECT_TARGET));
			return;
		}
		//Notify player and admin
		activeChar.sendMessage("You gave " + player.giveAvailableSkills(includedByFs, true) + " skills to " + player.getName());
		player.sendSkillList();
	}

To this 

 

public void sendSkillList()
	{
		sendSkillList(this);
	}

 

To this 

 

public void sendSkillList(final L2PcInstance player)
	{
		boolean isDisabled = false;
		final SkillList sl = new SkillList();
		
		if (player != null)
		{
			for (final L2Skill s : player.getAllSkills())
			{
				if (s == null)
				{
					continue;
				}
				if (s.getId() > 9000 && s.getId() < 9007)
				{
					continue;
				}
				if (_transformation != null && !containsAllowedTransformSkill(s.getId()) && !s.allowOnTransform())
				{
					continue;
				}
				if (player.getClan() != null)
				{
					isDisabled = s.isClanSkill() && player.getClan().getReputationScore() < 0;
				}
				boolean isEnchantable = SkillTable.getInstance().isEnchantable(s.getId());
				if (isEnchantable)
				{
					final L2EnchantSkillLearn esl = EnchantGroupsTable.getInstance().getSkillEnchantmentBySkillId(s.getId());
					if (esl != null)
					{
						if (s.getLevel() < esl.getBaseLevel())
						{
							isEnchantable = false;
						}
					}
					else
					{
						isEnchantable = false;
					}
				}
				if (getAioEndTime() > System.currentTimeMillis() && !isGM() && !isInsideZone(ZONE_TOWN))
				{
					isDisabled = true;
				}
				sl.addSkill(s.getId(), s.getLevel(), s.isPassive(), isDisabled, isEnchantable);
			}
		}
		
		sendPacket(sl);
	}

 

And stops. I use the admin command admin_give_all_skills  So is not SQL relative. Even if it was i have fast disk it wouldnt downgrade so much.

 

Link to comment
Share on other sites

Just now, .Elfocrash said:

Whats in 


player.getAllSkills()

public final L2Skill[] getAllSkills()
    {
        if (_skills == null)
        {
            return new L2Skill[0];
        }
        return _skills.values().toArray(new L2Skill[_skills.values().size()]);
    }

Map to array 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.




  • Posts

    • Hello everyone,    As you can see lately, the L2 community is decreasing, especially on private servers, its been 21 years since Lineage2 release date (1st October 2003). MaxCheaters.com was created in 2005 (with different names) and till today we are basically focused on Lineage 2. We made several attempts to add other games, but everyone still knew us as an L2 based forum. MaxCheaters has a long history and is one of the few forums that have survived to this day,It would be a shame to let the site die.   So I came up with a few ideas to improve it and follow the trends.   1. Create a utility token, (evm or solana), that will be used for several things such as: Staffers/moderators payment. Content creators reward system. (influencers/advertising/topic creators) Paid forum support. Exchanges and marketplaces . Lineage 2 utility token for private servers. Other MMO utility token for buying/selling accounts/gold etc. Maxcheaters fixed expenses/improvements/development/expansion/design/topsite   2. Reduce l2 sections, (we done this before) , and add more games on main page Less l2 sections More MMO games Focus on marketplaces    3. Rebuild staffers team/more events. Add one staffer per MMO game. More active staffers on our team.   4. Social media activity / streaming Twtter / TikTok content for gaming.  Streaming platforms (create official channel) Moderators/content creators for this content specifically.
    • From my personal experiences 🙂   Few months ago I decided to create my own Essence project. Project needs website, and I do not specialize in frontend development (t.y. i can make web work, but it won't be pretty for eye). So I search and find a guy in Discord, which claims he can make me a good looking HTML website for 30 EUR, prove some screenshots from his previous work. I agree. 1 week later, I get my HTML website, make few changes to contents, update URLs and upload it to FTP. Site looks good, I am happy that this headache is no more.   Few months passes. I randomly crawl through other Essence server websites scouting for good ideas for my own project. Suddenly one of russians project website opens and.. it's the same website as one I have 😉 perfectly absolutely same layout, colours, etc etc etc. I contact my guy to ask what the hell, to get blocked 😉  So I find a weekend worth of my time. Find HTML5 boilerplate generator and ask it to include Bootstrap 5 and some other stuff. Open Bootstrap documentation, drink two energy drinks on instant and start working my backend-inspired HTML black magic... Once I found suiting firefly effect for header, result looked oikay for me: Absolutely no magic or beauty here, but: * Unique (and probably nobody cares to rip it) * Done for free in ~10 hours by non-frontend dev * Most modern browsers friendly * Completely static content, loads instantly. No PHP at all * Sidebar statuses (online, pvp, pk) are pulled from account manager REST API endpoint and is cached for 5 minutes. Account manager runs separately from website frontend and has access to server DB. Where could/will it get better? * Code in Vue instead of HTML - time concerns only, but Vue is superior compared to HTML/PHP for supporting desktop/mobile, easing development by miles. Need to learn how to use it properly. * Way to manage content from backend - in my instance I think account manager is not really meant for that. Vue can help here too - there are components for content building. * Currently default Bootstrap components are used. Would be nice to have custom and more vibrant buttons. Guess what, Vue can help here too.   tl;dr don't buy 30EUR website, it will be ripped or shit. you better make your own website. Be curious. I am backend developer, I obviously have general idea how frontend works. But imho everyone who can make L2 server by editing NPC HTMLs, also can make their own simple website. ChatGPT and other AIs are your friends. Bootstrap. jQuery documentations are your friends. And when you feel good and comfortable with HTML, if you like, you can continue learning Vue, or going backend. Now, as for the top sites. You really need to invest money to make new project work. I mean really, really much money. For this concept to work, top website itself must get visited. But if you can sort that your top site would be popular amongst players, then it's a really very simple concept, as far as current 2004-ish sites goes. I think simple, working concept of this, maybe without proper frontend, but with implemented backend logics (add/edit/disable server, sort by votes count (top list), vote for server with verification, callback to server endpoint - all of that can be done using Symfony in mostly 5 days, with lots of breaks for coffee and a smoke 😉. Experienced mid frontend dev would make a Vue/React frontend for it in another 5 days. it's really really simple concept 🙂  
  • Topics

×
×
  • Create New...