Jump to content

Recommended Posts

Posted (edited)

Short version : upon L2PHX (or any packet manipulation tool) use, the manual or automatic send of EnterWorld packet creates issues (for example, if the config spawn protection is activated, it sends anew the spawn protection, making you immune everytime you send back the packet). Simply select EnterWorld packet from "Packet Sniffer" tab, "Add packet to send..." and check "send every 100 ms".

 

Issue : packet manipulation spam, calling multiple times the same subroutines (spawn protection custom and whatever custom you added in EnterWorld). Potentially fix other exploits based on your spawnMe() content.

 

Fix : generate a new GameClientState (personally called ENTERING), isolate EnterWorld on it (RequestManorList being called automatically, it must be part of ENTERING too). Any subsequent calls of EnterWorld will call onUnknownPacket, because it will be considered out of ENTERING scope, since we're already at IN_GAME scope once the Player instance is fully loaded (such stuff already exists for all packets : login packets can't be called during ingame state, etc. It's just than EnterWorld is a transition packet between lobby and ingame, but it is considered an ingame packet while it shouldn't).

 

Since chronicle got different opcodes, you have to adapt using your own chronicle opcodes. I can't and won't deliver a unique version for all chronicles. Since I'm an IL guy, I share for IL. The diff patch can help you to guess what to edit.

 

Possible improvements :

  • If you know more packets which should be sent only during that translation time between AUTHED and IN_GAME, you can answer here (notably for higher chronicles than IL) with your own version for your own chronicle. I will refresh the initial topic with the different versions.
  • Not sure if RequestManorList  can be called anywhere else (manor panel, etc). I preferred to keep it on IN_GAME. If you know the answer, consider to reply :) !

 

aCis version, based on latest (GameClient is generally called L2GameClient) :

 

### Eclipse Workspace Patch 1.0
#P aCis_gameserver
Index: java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java	(revision 1146)
+++ java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java	(working copy)
@@ -62,7 +62,7 @@
 					
 					sendPacket(SSQInfo.sendSky());
 					
-					client.setState(GameClientState.IN_GAME);
+					client.setState(GameClientState.ENTERING);
 					
 					sendPacket(new CharSelected(cha, client.getSessionId().playOkID1));
 				}
Index: java/net/sf/l2j/gameserver/network/GameClient.java
===================================================================
--- java/net/sf/l2j/gameserver/network/GameClient.java	(revision 1157)
+++ java/net/sf/l2j/gameserver/network/GameClient.java	(working copy)
@@ -64,6 +64,7 @@
 	{
 		CONNECTED, // client has just connected
 		AUTHED, // client has authed but doesnt has character attached to it yet
+		ENTERING, // client is currently loading his Player instance, but didn't end
 		IN_GAME // client has selected a char and is in game
 	}
@@ -168,6 +168,7 @@
 				case AUTHED:
 					return "[Account: " + getAccountName() + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
 				
+				case ENTERING:
 				case IN_GAME:
 					return "[Character: " + (getPlayer() == null ? "disconnected" : getPlayer().getName()) + " - Account: " + getAccountName() + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
 				
Index: java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java	(revision 1145)
+++ java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java	(working copy)
@@ -51,6 +51,7 @@
 						break;
 				}
 				break;
+				
 			case AUTHED:
 				switch (opcode)
 				{
@@ -80,6 +81,43 @@
 						break;
 				}
 				break;
+				
+			case ENTERING:
+				switch (opcode)
+				{
+					case 0x03:
+						msg = new EnterWorld();
+						break;
+						
+					case 0xd0:
+						int id2 = -1;
+						if (buf.remaining() >= 2)
+						{
+							id2 = buf.getShort() & 0xffff;
+						}
+						else
+						{
+							_log.warning("Client: " + client.toString() + " sent a 0xd0 without the second opcode.");
+							break;
+						}
+						
+						switch (id2)
+						{
+							case 8:
+								msg = new RequestManorList();
+								break;
+							default:
+								printDebugDoubleOpcode(opcode, id2, buf, state, client);
+								break;
+						}
+						break;
+						
+					default:
+						printDebug(opcode, buf, state, client);
+						break;
+				}
+				break;
+				
 			case IN_GAME:
 				switch (opcode)
 				{
@@ -89,9 +127,6 @@
 					// case 0x02:
 					// // Say ... not used any more ??
 					// break;
-					case 0x03:
-						msg = new EnterWorld();
-						break;
 					case 0x04:
 						msg = new Action();
 						break;
Index: java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java	(revision 1150)
+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java	(working copy)
@@ -35,6 +35,7 @@
 import net.sf.l2j.gameserver.model.pledge.SubPledge;
 import net.sf.l2j.gameserver.model.zone.ZoneId;
 import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.GameClient.GameClientState;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.Die;
 import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
@@ -77,6 +78,8 @@
 			return;
 		}
 		
+		getClient().setState(GameClientState.IN_GAME);
+		
 		final int objectId = player.getObjectId();
 		
 		if (player.isGM())

 

Edited by Tryskell
  • Like 1
  • Upvote 6
Posted

Dude you still share shit? It's like making my stomach feel weird, like in a good way tho.

Gotta have to wait for my reacts to cool down.

 

Nice to see ya <3

Posted
54 minutes ago, Setekh said:

Dude you still share shit? It's like making my stomach feel weird, like in a good way tho.

Gotta have to wait for my reacts to cool down.

 

Nice to see ya <3

 

I only share public exploits fixes, and help on dev help section when the question is ok. Which is still far better than some others ppl.

 

You maybe should check for chestburster if you got stomach problems. :cheer:

Posted

it was possible to lag servers using that years ago cuz it init all enterworld steps and has no flood protection :D

but beside that its useless, it didn't give you spawn protection on H5+ back in days (mobs will just still attack you).

Posted (edited)

Tryskell made 2 share in 1 month. Now we all need 2 revision of aCis in same year and its cleary a sign of the end of the world!

 

Also "Little weird orange hair dwarf make aliens movie reference in a gaming forum", cliche. +1 SIN

Edited by Kara`
Posted (edited)
6 minutes ago, Kara` said:

Tryskell made 2 share in 1 month. Now we all need 2 revision of aCis in same year and its cleary a sign of the end of the world!

 

I'm already at 3 revs for the 2 current months and a 4th is coming, you should review your statistics.

 

Should I ask a rename for Nibiru ?

Edited by Tryskell
Posted
6 minutes ago, Tryskell said:

 

I'm already at 3 revs for the 2 current months and a 4th is coming, you should review your statistics.

 

Should I ask a rename for Nibiru ?

This would be a hit don't mess with your luck tryski

Kt3K0Pa.jpg

Posted
25 minutes ago, Tryskell said:

You maybe should check for chestburster if you got stomach problems. :cheer:

Hahaha, didnt expect that one, nais :D

Posted (edited)
56 minutes ago, AlmostGood said:

it was possible to lag servers using that years ago cuz it init all enterworld steps and has no flood protection :D

but beside that its useless, it didn't give you spawn protection on H5+ back in days (mobs will just still attack you).

 

The only people you can spam is actually... The hacker. Cause the hacker sends to himself 10+ packets everytime, the packet queue is simply growing and you end with unresponsive client (with 100ms at least, on aCis). And EnterWorld barely sends anything as broadcast.

 

The problem is more about called methods, notably spawnMe() and customs. Imagine let's say, a custom counter which resets on EnterWorld (since EnterWorld is a really common place to edit for customs), you only have to send back EnterWorld to reset that custom counter.

 

All in one, EnterWorld isn't supposed to be called anytime after first call. So even on a logic base, it should be restrained to a single call, with a unique call window (being between CharacterSelected and EnterWorld first call).

Edited by Tryskell
Posted (edited)
8 hours ago, Tryskell said:

 

The only people you can spam is actually... The hacker. Cause the hacker sends to himself 10+ packets everytime, the packet queue is simply growing and you end with unresponsive client (with 100ms at least, on aCis). And EnterWorld barely sends anything as broadcast.

 

I wrote lag not spam

around 2-3 years back it only required ~5 clients running flooding script with no delay (which also dropped all related answers from server to dont kill client) to lag whole server to the unplayable point (h5 tales pack).

 

About lagging ppl around by broadcast its even more trivial, it only requires 1 client and ppl around wont be able to move. Most l2j packs have at least few non flood protected packets which can be used, dunno about acis but if you didn't rework that part its prolly no different.

Edited by AlmostGood
Posted

Fix is slightly edited. Don't forget to add

case ENTERING:

on L2GameClient#toString, on the same level than case IN_GAME.
 

                case ENTERING:
                case IN_GAME:
                    return...

 

  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Posts

    • what pack you use  send me on discord for it
    • package custom.events.RandomZoneEvent; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.ScheduledFuture; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.commons.time.SchedulingPattern; import org.l2jmobius.commons.time.TimeUtil; import org.l2jmobius.commons.util.IXmlReader; import org.l2jmobius.gameserver.managers.ZoneManager; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.quest.Event; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneType; import org.l2jmobius.gameserver.model.zone.type.RandomZone; import org.l2jmobius.gameserver.util.Broadcast; /** * Random Zone Event - Activates one random PvP zone temporarily. No modifica la clase de la zona: usa flags PvP en runtime. * @author Juan */ public class RandomZoneEvent extends Event { private static final String CONFIG_FILE = "data/scripts/custom/events/RandomZoneEvent/config.xml"; private static int EVENT_DURATION_MINUTES = 15; private static boolean _isActive = false; private ScheduledFuture<?> _eventTask = null; private final List<ZoneType> _availableZones = new ArrayList<>(); private ZoneType _activeZone = null; public RandomZoneEvent() { loadConfig(); loadZones(); registerZoneListeners(); } /** * Registra listeners a TODAS LAS ZONAS random */ private void registerZoneListeners() { for (ZoneType zone : _availableZones) { addEnterZoneId(zone.getId()); addExitZoneId(zone.getId()); LOGGER.info("[RandomZoneEvent] Registered listener for zone: " + zone.getName()); } } private void loadConfig() { new IXmlReader() { @Override public void load() { parseDatapackFile(CONFIG_FILE); } @Override public void parseDocument(Document doc, File file) { forEach(doc, "event", eventNode -> { final StatSet att = new StatSet(parseAttributes(eventNode)); final String name = att.getString("name"); for (Node node = eventNode.getFirstChild(); node != null; node = node.getNextSibling()) { if ("schedule".equals(node.getNodeName())) { final StatSet attributes = new StatSet(parseAttributes(node)); final String pattern = attributes.getString("pattern"); final SchedulingPattern schedulingPattern = new SchedulingPattern(pattern); final StatSet params = new StatSet(); params.set("Name", name); params.set("SchedulingPattern", pattern); final long delay = schedulingPattern.getDelayToNextFromNow(); getTimers().addTimer("Schedule_" + name, params, delay + 5000, null, null); LOGGER.info("[RandomZoneEvent] Event " + name + " scheduled at " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay)); } } }); } }.load(); } private void loadZones() { for (ZoneType zone : ZoneManager.getInstance().getAllZones(RandomZone.class)) { if ((zone.getName() != null) && zone.getName().toLowerCase().startsWith("random_zone")) { _availableZones.add(zone); LOGGER.info("[RandomZoneEvent] Loaded zone: " + zone.getName() + " (id=" + zone.getId() + ")"); } } LOGGER.info("[RandomZoneEvent] Total random zones loaded: " + _availableZones.size()); } @Override public void onTimerEvent(String event, StatSet params, Npc npc, Player player) { if (event.startsWith("Schedule_")) { eventStart(null); final SchedulingPattern schedulingPattern = new SchedulingPattern(params.getString("SchedulingPattern")); final long delay = schedulingPattern.getDelayToNextFromNow(); getTimers().addTimer(event, params, delay + 5000, null, null); LOGGER.info("[RandomZoneEvent] Rescheduled for " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay)); } } @Override public boolean eventStart(Player eventMaker) { if (_isActive) { if (eventMaker != null) { eventMaker.sendMessage("RandomZoneEvent already active."); } return false; } if (_availableZones.isEmpty()) { Broadcast.toAllOnlinePlayers("[RandomZoneEvent] No zones configured."); return false; } _isActive = true; Broadcast.toAllOnlinePlayers("⚔️ Random Zone Event has started!"); _eventTask = ThreadPool.schedule(this::activateRandomZone, 5_000); return true; } private void activateRandomZone() { _activeZone = _availableZones.get(new Random().nextInt(_availableZones.size())); _activeZone.setEnabled(true); Broadcast.toAllOnlinePlayers("🔥 Random Zone Event: " + _activeZone.getName() + " is now PvP for " + EVENT_DURATION_MINUTES + " minutes!"); _eventTask = ThreadPool.schedule(this::eventStop, EVENT_DURATION_MINUTES * 60 * 1000L); } @Override public boolean eventStop() { if (!_isActive) { return false; } _isActive = false; if (_eventTask != null) { _eventTask.cancel(true); _eventTask = null; } if (_activeZone != null) { _activeZone.setEnabled(false); Broadcast.toAllOnlinePlayers("🏁 Random Zone Event ended. " + _activeZone.getName() + " is back to normal."); _activeZone = null; } else { Broadcast.toAllOnlinePlayers("🏁 Random Zone Event ended."); } return true; } @Override public void onEnterZone(Creature creature, ZoneType zone) { if (!_isActive || (_activeZone == null)) { return; } if ((zone == _activeZone) && creature.isPlayable()) { creature.setInsideZone(ZoneId.PVP, true); if (creature.isPlayer()) { creature.sendMessage("Esta zona está en modo PvP temporalmente."); } } } @Override public void onExitZone(Creature creature, ZoneType zone) { if (!_isActive || (_activeZone == null)) { return; } if ((zone == _activeZone) && creature.isPlayable()) { creature.setInsideZone(ZoneId.PVP, false); if (creature.isPlayer()) { creature.sendMessage("Abandonaste la zona PvP temporal."); } } } @Override public boolean eventBypass(Player player, String bypass) { return true; } @Override public String onEvent(String event, Npc npc, Player player) { return super.onEvent(event, npc, player); } @Override public String onFirstTalk(Npc npc, Player player) { return null; } public static void main(String[] args) { new RandomZoneEvent(); } } i have this but its not working
    • ZonePvPSpawnBossRadio=0 ZonePvPSpawnBossBarakiel=0 at the Customs.ini in L2Server folder. Im prety sure this is it because i had the same problem with you in cruma 1 floor for example and i couldn't fix it but i fixed it finally by changing these 2 lines
    • Siege Reward Start PM Msg Rework Config root BossDieAnnounce and BossDieSound in the L24Team.properties and Config.java files for global raid boss death notifications and sounds. Adds a new reward_list table to the DB.sql file to track castle rewards. Improves character creation logic for thread safety and validation. Adds extensive state checks to the RequestEnchantItem method to prevent enchantments during inappropriate player states. Fixed auto-attack animation bug (there was no attack animation, only damage animation) Clean Code Other fixes I forgot to list! Java 14 Fixed issue where deleting a character would prevent it from leaving the screen or being removed, or even after a delete CD (it would only exit when re-logging in or creating a new character). Added Premium System from the other C2 project (Needs testing and improvement). Added the "Improved" Community Board (incomplete).
  • Topics

×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock