View difference between Paste ID: EizF3V4k and 974V2p2p
SHOW: | | - or go back to the newest paste.
1
diff --git a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java b/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java
2
new file mode 100644
3
index 0000000..6b7ef6f
4
--- /dev/null
5
+++ a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java
6
@@ -0,0 +1,98 @@
7
+package net.sf.l2j.gameserver.taskmanager;
8
+
9
+import java.security.SecureRandom;
10
+import java.util.ArrayList;
11
+import java.util.logging.Logger;
12
+
13
+import net.sf.l2j.commons.random.Rnd;
14
+
15
+import net.sf.l2j.gameserver.data.manager.ZoneManager;
16
+import net.sf.l2j.gameserver.enums.ZoneId;
17
+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone;
18
+import net.sf.l2j.gameserver.model.World;
19
+import net.sf.l2j.gameserver.model.actor.Player;
20
+import net.sf.l2j.gameserver.model.location.Location;
21
+import net.sf.l2j.gameserver.model.zone.type.SoloZone;
22
+
23
+
24
+/**
25
+ * @author MarGaZeaS
26
+ */
27
+public class SoloZoneTaskManager implements Runnable {
28
+
29
+    private static final Location EXIT_LOCATION = VoiceExitSoloZone.getExitLocation(); // Λαμβάνουμε την έξοδο από το VoiceExitSoloZone
30
+
31
+    @Override
32
+    public void run()
33
+    {
34
+        // Διασχίζουμε όλους τους παίκτες του κόσμου
35
+        for (Player player : World.getInstance().getPlayers())
36
+        {
37
+            // Ελέγχουμε αν ο παίκτης είναι στο SoloZone
38
+            if (player.isInsideZone(ZoneId.SOLO))
39
+            {
40
+                // Μεταφέρουμε τον παίκτη στην έξοδο
41
+                player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0);
42
+                player.sendMessage("The server is restarting, you have been moved out of the Solo Zone.");
43
+            }
44
+        }
45
+    }
46
+    
47
+	private int _id;
48
+	
49
+    private static final Logger _log = Logger.getLogger(SoloZoneTaskManager.class.getName());
50
+    private static final ArrayList<String> _rndNames = new ArrayList<>();
51
+    private static final int RANDOM_NAMES = 500;
52
+    private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
53
+    private int _playersInSoloZone = 0;
54
+
55
+    public int getPlayersInside() {
56
+        return _playersInSoloZone;
57
+    }
58
+
59
+    public void setPlayersInside(int val) {
60
+        _playersInSoloZone = val;
61
+    }
62
+
63
+    public SoloZoneTaskManager() {
64
+        _log.info("Solo Zone System: Loading...");
65
+        for (int i = 0; i < RANDOM_NAMES; i++) {
66
+            String name = generateName();
67
+            _rndNames.add(name);
68
+            _log.info("Generated name: " + name);
69
+        }
70
+        _log.info("Solo Zone System: Loaded " + _rndNames.size() + " names.");
71
+    }
72
+
73
+    public String getAName() {
74
+        if (_rndNames.isEmpty()) {
75
+            _log.warning("SoloZoneManager: No random names available.");
76
+            return "Unknown";
77
+        }
78
+        return _rndNames.get(Rnd.get(5, RANDOM_NAMES - 5));
79
+    }
80
+    
81
+    private static String generateName() {
82
+        SecureRandom rnd = new SecureRandom();
83
+        StringBuilder sb = new StringBuilder(15);
84
+        for (int i = 0; i < 15; i++) {
85
+            sb.append(CHARS.charAt(rnd.nextInt(CHARS.length())));
86
+        }
87
+        return sb.toString();
88
+    }
89
+    
90
+ 	public int getZoneId()
91
+ 	{
92
+ 		return _id;
93
+ 	}
94
+ 	
95
+ 	public final static SoloZone getCurrentZone() {
96
+ 	    return ZoneManager.getInstance().getAllZones(SoloZone.class)
97
+ 	        .stream()
98
+ 	        .findFirst() // Επιστρέφει την πρώτη SoloZone (αν υπάρχει μόνο μία)
99
+ 	        .orElse(null);
100
+ 	}
101
+	
102
+    public static SoloZoneTaskManager getInstance() {
103
+        return SingletonHolder._instance;
104
+    }
105
+
106
+    private static class SingletonHolder {
107
+        private static final SoloZoneTaskManager _instance = new SoloZoneTaskManager();
108
+    }
109
+}
110
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java b/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java
111
index a707ce5..d247e2e 100644
112
--- a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java
113
			final Player player = entry.getKey();
114
			final long timeLeft = entry.getValue();
115
			
116
+			if(player.isInsideZone(ZoneId.SOLO))
117
+				continue;
118
			
119
			if(player.isInsideZone(ZoneId.BOSS))
120
				continue;
121
			
122
			// Time is running out, clear PvP flag and remove from list.
123
			if (currentTime > timeLeft)
124
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java
125
index a707ce5..d247e2e 100644
126
+++ b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java
127
128
		if (Config.ALLOW_FISH_CHAMPIONSHIP)
129
			FishingChampionshipManager.getInstance();
130
131
+		if (Config.ENABLE_STARTUP)
132
+		StartupManager.getInstance();			
133
134
diff --git a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java
135
new file mode 100644
136
index 0000000..6b7ef6f
137
--- /dev/null
138
+++ a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java
139
		if (!st.hasMoreTokens())
140
		{
141
			sendHtmlForm(player);
142
			return;
143
		}
144
		
145
		try
146
		{
147
			switch (st.nextToken())
148
			{
149
				case "shutdown":
150
+	                SoloZoneTaskManager exitTask = new SoloZoneTaskManager();
151
+	                ThreadPool.schedule(exitTask, 0); 
152
					Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), false);
153
					break;
154
				
155
				case "restart":
156
+	                exitTask = new SoloZoneTaskManager();
157
+	                ThreadPool.schedule(exitTask, 0); 
158
					Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), true);
159
					break;
160
				
161
				case "abort":
162
					Shutdown.getInstance().abort(player);
163
					break;
164
diff --git a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java b/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java
165
new file mode 100644
166
index 0000000..6b7ef6f
167
--- /dev/null
168
+++ a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java
169
+package net.sf.l2j.gameserver.handler.voicecommandhandlers;
170
+
171
+import net.sf.l2j.commons.pool.ThreadPool;
172
+
173
+import net.sf.l2j.gameserver.enums.ZoneId;
174
+import net.sf.l2j.gameserver.handler.IVoiceCommandHandler;
175
+import net.sf.l2j.gameserver.model.actor.Player;
176
+import net.sf.l2j.gameserver.model.location.Location;
177
+import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
178
+
179
+/**
180
+ * Handles the voice command for exiting the Solo Zone with delay and effects.
181
+ * 
182
+ * @author MarGaZeaS
183
+ */
184
+public class VoiceExitSoloZone implements IVoiceCommandHandler
185
+{
186
+    private static final String[] VOICE_COMMANDS =
187
+    {
188
+        "exit"
189
+    };
190
+
191
+    // Default location to teleport players when exiting the Solo Zone
192
+    private static final Location EXIT_LOCATION = new Location(81318, 148064, -3464); // Replace with your desired coordinates
193
+
194
+    // Προσθήκη της μεθόδου για να πάρουμε την τοποθεσία εξόδου
195
+    public static Location getExitLocation() {
196
+        return EXIT_LOCATION;
197
+    }
198
+
199
+    @Override
200
+    public void useVoiceCommand(Player player, String command)
201
+    {
202
+        if (command.equalsIgnoreCase("exit"))
203
+        {
204
+            if (!player.isInsideZone(ZoneId.SOLO))
205
+            {
206
+                player.sendMessage("You are not inside the Solo Zone.");
207
+                return;
208
+            }
209
+
210
+            // Notify the player about the delay
211
+            player.sendMessage("You will be teleported out of the Solo Zone in 2 seconds.");
212
+            
213
+            // Cast skill effect (Skill ID: 2100, Level: 1)
214
+            player.broadcastPacket(new MagicSkillUse(player, player, 2100, 1, 2000, 0));
215
+            
216
+            // Schedule the teleportation after a 2-second delay
217
+            ThreadPool.schedule(() -> {
218
+                // Teleport the player to the designated exit location
219
+                player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0);
220
+
221
+                // Inform the player
222
+                player.sendMessage("You have exited the Solo Zone.");
223
+            }, 2000); // Delay in milliseconds (2000ms = 2 seconds)
224
+        }
225
+    }
226
+
227
+    @Override
228
+    public String[] getVoiceCommandList()
229
+    {
230
+        return VOICE_COMMANDS;
231
+    }
232
+}
233
diff --git a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java b/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java
234
new file mode 100644
235
index 0000000..6b7ef6f
236
--- /dev/null
237
+++ a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java
238
public class VoiceCommandHandler
239
{
240
	private final Map<String, IVoiceCommandHandler> _entries = new HashMap<>();
241
	
242
	protected VoiceCommandHandler()
243
	{
244
		............
245
		............
246
+		registerHandler(new VoiceExitSoloZone());
247
		
248
	}
249
	
250
	public void registerHandler(IVoiceCommandHandler handler)
251
	{
252
		for (String command : handler.getVoiceCommandList())
253
			_entries.put(command, handler);
254
	}
255
diff --git a/java/net/sf/l2j/gameserver/model/actor/Npc.java b/java/net/sf/l2j/gameserver/model/actor/Npc.java
256
new file mode 100644
257
index 0000000..6b7ef6f
258
--- /dev/null
259
+++ a/java/net/sf/l2j/gameserver/model/actor/Npc.java
260
		else if (command.startsWith("Chat"))
261
		{
262
			int val = 0;
263
			try
264
			{
265
				val = Integer.parseInt(command.substring(5));
266
			}
267
			catch (final IndexOutOfBoundsException ioobe)
268
			{
269
			}
270
			catch (final NumberFormatException nfe)
271
			{
272
			}
273
			
274
			showChatWindow(player, val);
275
+		)
276
+		else if (command.startsWith("solopvp"))
277
+		{
278
+		    SoloZoneTaskManager.getInstance();
279
+		    player.teleportTo(SoloZoneTaskManager.getCurrentZone().getLoc(), 25);
280
+		}
281
		else if (command.startsWith("Link"))
282
		{
283
			final String path = command.substring(5).trim();
284
			if (path.indexOf("..") != -1)
285
				return;
286
			
287
			final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
288
			html.setFile("data/html/" + path);
289
			html.replace("%objectId%", getObjectId());
290
			player.sendPacket(html);
291
		}
292
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java
293
new file mode 100644
294
index 0000000..6b7ef6f
295
--- /dev/null
296
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java
297
		// Fixed.
298
-		else if (_requestType == 4)
299
-		{
300
-			if (!player.isGM() && !player.isFestivalParticipant())
301
-				return;
302
-			
303
-			loc = player.getPosition();
304
-		}
305
+		if (_requestType == 4) 
306
+		{
307
+		    // Έλεγχος αν ο παίκτης δεν είναι GM, δεν είναι μέρος του φεστιβάλ και δεν είναι στην Solo Zone
308
+		    if (!player.isGM() && !player.isFestivalParticipant() && !player.isInsideZone(ZoneId.SOLO)) 
309
+		    {
310
+		        return;
311
+		    }
312
+
313
+		    SoloZoneTaskManager.getInstance();
314
+			SoloZone currentZone = SoloZoneTaskManager.getCurrentZone();
315
+		    if (currentZone != null && currentZone.getLoc() != null) 
316
+		    {
317
+		        // Αν υπάρχει ζώνη και οι τοποθεσίες δεν είναι κενές, χρησιμοποιούμε τυχαία τοποθεσία από την ζώνη
318
+		        loc = currentZone.getLoc();
319
+		    } else 
320
+		    {
321
+		        // Διαφορετικά, κάνουμε respawn στην τρέχουσα θέση του παίκτη
322
+		        loc = player.getPosition();
323
+		    }
324
+		}
325
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
326
new file mode 100644
327
index 0000000..6b7ef6f
328
--- /dev/null
329
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
330
		if (player.isFestivalParticipant() && FestivalOfDarknessManager.getInstance().isFestivalInitialized())
331
		{
332
			player.sendPacket(SystemMessageId.NO_RESTART_HERE);
333
			sendPacket(RestartResponse.valueOf(false));
334
			return;
335
		}
336
 		
337
+        if (player.isInsideZone(ZoneId.SOLO))
338
+        {
339
+            player.sendMessage("You cannot restart your character while in Solo Zone. Use .exit to leave");
340
+            player.setFakeName(null);
341
+            sendPacket(RestartResponse.valueOf(false));
342
+            return;
343
+        }
344
        
345
		player.removeFromBossZone();
346
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java b/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
347
new file mode 100644
348
index 0000000..6b7ef6f
349
--- /dev/null
350
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
351
		player.removeFromBossZone();
352
		player.logout(true);
353
	}
354
}
355
+
356
+ 	    if (player.isInsideZone(ZoneId.SOLO))
357
+ 	    {
358
+ 	        player.sendMessage("You cannot logout or restart your character while in Solo Zone. Use .exit to leave");
359
+ 	        player.setFakeName(null); 
360
+ 	        player.sendPacket(ActionFailed.STATIC_PACKET);
361
+ 	        return;
362
+ 	    }
363
+ 	    
364
		player.removeFromBossZone();
365
		player.logout(true);
366
	}
367
}
368
diff --git a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java b/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java
369
new file mode 100644
370
index 0000000..6b7ef6f
371
--- /dev/null
372
+++ a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java
373
+package net.sf.l2j.gameserver.model.zone.type;
374
+
375
+import java.util.ArrayList;
376
+import java.util.List;
377
+import java.util.Random;
378
+
379
+import net.sf.l2j.commons.random.Rnd;
380
+
381
+import net.sf.l2j.Config;
382
+import net.sf.l2j.gameserver.enums.MessageType;
383
+import net.sf.l2j.gameserver.enums.ZoneId;
384
+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone;
385
+import net.sf.l2j.gameserver.model.World;
386
+import net.sf.l2j.gameserver.model.actor.Creature;
387
+import net.sf.l2j.gameserver.model.actor.Player;
388
+import net.sf.l2j.gameserver.model.location.Location;
389
+import net.sf.l2j.gameserver.model.zone.type.subtype.ZoneType;
390
+import net.sf.l2j.gameserver.network.SystemMessageId;
391
+import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
392
+import net.sf.l2j.gameserver.taskmanager.PvpFlagTaskManager;
393
+import net.sf.l2j.gameserver.taskmanager.SoloZoneTaskManager;
394
+
395
+/**
396
+ * @author MarGaZeaS
397
+ *
398
+ */
399
+public class SoloZone extends ZoneType
400
+{
401
+	private String _name;
402
+	private List<Location> _locations = new ArrayList<>();
403
+    
404
+	public SoloZone(int id)
405
+	{
406
+		super(id);
407
+	}
408
+	
409
+ 	@Override
410
+ 	public void setParameter(String name, String value)
411
+ 	{
412
+ 		if (name.equals("name"))
413
+ 			_name = value;
414
+        else if (name.equals("locs")) 
415
+        {
416
+            for (String locs : value.split(";")) 
417
+            {
418
+                String[] coordinates = locs.split(",");
419
+                if (coordinates.length == 3) 
420
+                {
421
+                    int x = Integer.parseInt(coordinates[0]);
422
+                    int y = Integer.parseInt(coordinates[1]);
423
+                    int z = Integer.parseInt(coordinates[2]);
424
+                    _locations.add(new Location(x, y, z));
425
+                } 
426
+                else 
427
+                {
428
+                    LOGGER.warn("Invalid location format: " + locs);
429
+                }
430
+            }
431
+        }
432
+    }
433
+ 	
434
+
435
+	@Override
436
+	protected void onEnter(Creature character) 
437
+	{
438
+	    if (character instanceof Player) 
439
+	    {
440
+	        final Player player = (Player) character;
441
+            
442
+	        if ((player.getClassId().getId() == 15 || player.getClassId().getId() == 16 || player.getClassId().getId() == 97))
443
+	        {
444
+	            Location respawnLocation = VoiceExitSoloZone.getExitLocation();
445
+	            player.instantTeleportTo(respawnLocation, 20);
446
+	            player.sendMessage("Your class is not allowed in this zone.");
447
+	            return;
448
+	        }
449
+			
450
+	        String randomName = SoloZoneTaskManager.getInstance().getAName();
451
+	        if (randomName == null || randomName.isEmpty() || !isValidName(randomName)) 
452
+	        {
453
+	            randomName = generateRandomName(); 
454
+	        }
455
+	        if (isNameAlreadyTaken(randomName)) 
456
+	        {
457
+	            randomName = generateRandomName();
458
+	        }
459
+	        player.setFakeName(randomName);
460
+	        player.sendMessage("Welcome to the Solo Zone, your random name is: " + randomName);
461
+	        player.sendPacket(SystemMessageId.ENTERED_COMBAT_ZONE);
462
+	        character.setInsideZone(ZoneId.SOLO, true);
463
+	        character.setInsideZone(ZoneId.NO_STORE, true);
464
+	        character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, true);
465
+	        
466
+	        if (player.getParty() != null) 
467
+	        {
468
+	            player.getParty().removePartyMember(player, MessageType.DISCONNECTED);
469
+	        }
470
+	        
471
+	        if (player.getPvpFlag() > 0) 
472
+	            PvpFlagTaskManager.getInstance().remove(player, true);
473
+	        
474
+	        player.updatePvPStatus();
475
+	        player.broadcastUserInfo();
476
+	    }
477
+	}
478
+	    
479
+	private static boolean isValidName(String name) {
480
+	    return name.matches("[a-zA-Z0-9_]+");
481
+	}
482
+
483
+	private static String generateRandomName() {
484
+	    Random rand = new Random();
485
+	    int nameLength = rand.nextInt(12) + 4;
486
+	    StringBuilder nameBuilder = new StringBuilder();
487
+	    
488
+	    for (int i = 0; i < nameLength; i++) {
489
+	        char randomChar = (char) (rand.nextInt(26) + 'a');
490
+	        nameBuilder.append(randomChar);
491
+	    }
492
+
493
+	    return nameBuilder.toString();
494
+	}
495
+
496
+	private static boolean isNameAlreadyTaken(String name) {
497
+	    return World.getInstance().getPlayers().stream().anyMatch(player -> player.getFakeName().equals(name));
498
+	}
499
+	
500
+	@Override
501
+	protected void onExit(Creature character)
502
+	{
503
+		character.setInsideZone(ZoneId.SOLO, false); // Solo zone
504
+		character.setInsideZone(ZoneId.NO_STORE, false); // Allow making a store
505
+		character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, false); // Allow summon
506
+		
507
+		if (character instanceof Player)
508
+		{
509
+			final Player player = (Player) character;
510
+			
511
+	        if (player.getFakeName() != null)
512
+	        {
513
+	            player.setFakeName(null);
514
+	        }
515
+
516
+	        player.sendPacket(SystemMessageId.LEFT_COMBAT_ZONE);
517
+			{
518
+				if(!player.isInObserverMode() && player.getPvpFlag() > 0)
519
+					PvpFlagTaskManager.getInstance().add(player, Config.PVP_NORMAL_TIME);
520
+				
521
+				player.sendPacket(new EtcStatusUpdate(player));
522
+				player.broadcastUserInfo();
523
+			}
524
+		}
525
+	}
526
+ 	
527
+ 	public String getName()
528
+ 	{
529
+ 		return _name;
530
+ 	}
531
+ 	
532
+ 	public Location getLoc() 
533
+ 	{
534
+ 	    if (_locations.isEmpty()) 
535
+ 	    {
536
+ 	        return null;  // Αν η λίστα είναι κενή, επιστρέφουμε null
537
+ 	    }
538
+ 	    return _locations.get(Rnd.get(0, _locations.size() - 1));  // Επιλέγουμε τυχαία τοποθεσία
539
+ 	}
540
+}
541
diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/GameServer.java
542
new file mode 100644
543
index 0000000..6b7ef6f
544
--- /dev/null
545
+++ a/java/net/sf/l2j/gameserver/GameServer.java
546
		if (Config.ALLOW_FISH_CHAMPIONSHIP)
547
			FishingChampionshipManager.getInstance();
548
549
+		StringUtil.printSection("Custom Features");
550
+ 		SoloZoneTaskManager.getInstance();
551
552
		StringUtil.printSection("Handlers");
553
		LOGGER.info("Loaded {} admin command handlers.", AdminCommandHandler.getInstance().size());
554
diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/Shutdown.java
555
new file mode 100644
556
index 0000000..6b7ef6f
557
--- /dev/null
558
+++ a/java/net/sf/l2j/gameserver/Shutdown.java
559
			// disconnect players
560
			try
561
			{
562
				disconnectAllPlayers();
563
				LOGGER.info("All players have been disconnected.");
564
			}
565
			catch (Exception e)
566
			{
567
				// Silent catch.
568
			}
569
			        
570
+			// Restore real names for players in SoloZone
571
+			restoreRealNamesInSoloZone();
572
			
573
			// stop all threadpolls
574
			ThreadPool.shutdown();
575
			
576
			try
577
			{
578
				LoginServerThread.getInstance().interrupt();
579
			}
580
			catch (Exception e)
581
			{
582
				// Silent catch.
583
			}
584
			
585
			
586
			
587
				// avoids new players from logging in
588
				if (_secondsShut <= 60 && LoginServerThread.getInstance().getServerType() != ServerType.DOWN)
589
					LoginServerThread.getInstance().setServerType(ServerType.DOWN);
590
				
591
				_secondsShut--;
592
				
593
				Thread.sleep(1000);
594
			}
595
		}
596
		catch (InterruptedException e)
597
		{
598
		}
599
	}
600
	
601
+ 	// This method restores the real names of players in SoloZone
602
+ 	private static void restoreRealNamesInSoloZone()
603
+ 	{
604
+ 		for (Player player : World.getInstance().getPlayers())
605
+ 		{
606
+ 			// Check if player is inside the SoloZone
607
+ 			if (player.isInsideZone(ZoneId.SOLO))
608
+ 			{
609
+ 				// Restore the real name by removing the fake name
610
+ 				if (player.getFakeName() != null)
611
+ 				{
612
+ 					player.setFakeName(null);  // Restore the real name
613
+ 					LOGGER.info("Player {}'s fake name has been removed and real name restored.", player.getName());
614
+ 				}
615
+ 			}
616
+ 		}
617
+ 	}
618
 	
619
	private static void sendServerQuit(int seconds)
620
	{
621
		World.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_SERVER_WILL_BE_COMING_DOWN_IN_S1_SECONDS).addNumber(seconds));
622
	}
623
diff --git a/java/net/sf/l2j/gameserver/enums/ZoneId.java b/java/net/sf/l2j/gameserver/enums/ZoneId.java
624
new file mode 100644
625
index 0000000..6b7ef6f
626
--- /dev/null
627
+++ a/java/net/sf/l2j/gameserver/enums/ZoneId.java
628
public enum ZoneId
629
{
630
	PVP(0),
631
	PEACE(1),
632
	SIEGE(2),
633
	MOTHER_TREE(3),
634
	CLAN_HALL(4),
635
	NO_LANDING(5),
636
	WATER(6),
637
	JAIL(7),
638
	MONSTER_TRACK(8),
639
	CASTLE(9),
640
	SWAMP(10),
641
	NO_SUMMON_FRIEND(11),
642
	NO_STORE(12),
643
	TOWN(13),
644
	HQ(14),
645
	DANGER_AREA(15),
646
	CAST_ON_ARTIFACT(16),
647
	NO_RESTART(17),
648
	SCRIPT(18),
649
-	BOSS(19),
650
+	BOSS(19),
651
+	SOLO(20);
652
	
653
	private final int _id;
654
	
655
	private ZoneId(int id)
656
	{
657
		_id = id;
658
	}
659
diff --git a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java b/java/net/sf/l2j/gameserver/network/serverpackets/Die.java
660
new file mode 100644
661
index 0000000..6b7ef6f
662
--- /dev/null
663
+++ a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java
664
		if (creature instanceof Player)
665
		{
666
			Player player = (Player) creature;
667
-			_allowFixedRes = player.getAccessLevel().allowFixedRes();
668
+			_allowFixedRes = player.getAccessLevel().allowFixedRes() || player.isInsideZone(ZoneId.SOLO);
669
			_clan = player.getClan();
670
			
671
		}
672
diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver//model/actor/Player.java
673
new file mode 100644
674
index 0000000..6b7ef6f
675
--- /dev/null
676
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
677
		// Attacker or spectator logging into a siege zone will be ported at town.
678
		if (player.isInsideZone(ZoneId.SIEGE) && player.getSiegeState() < 2)
679
			player.teleportTo(TeleportType.TOWN);
680
		
681
+		if (player.isInsideZone(ZoneId.SOLO)) 
682
+		{
683
+		    ThreadPool.schedule(() -> {
684
+		        Location exitLocation = VoiceExitSoloZone.getExitLocation();
685
+		        
686
+		        if (exitLocation != null) 
687
+		        {
688
+		            player.teleportTo(exitLocation.getX(), exitLocation.getY(), exitLocation.getZ(), 0);
689
+		            player.sendMessage("You have been moved to the exit of the SoloZone.");
690
+		        }
691
+		    }, 5000); // 5000 milliseconds (5sec)
692
+		}
693
diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver/model/actor/Player.java
694
new file mode 100644
695
index 0000000..6b7ef6f
696
--- /dev/null
697
+++ a/java/net/sf/l2j/gameserver/model/actor/Player.java
698
	@Override
699
	public void doRevive()
700
	{
701
		super.doRevive();
702
		
703
		stopEffects(EffectType.CHARM_OF_COURAGE);
704
		sendPacket(new EtcStatusUpdate(this));
705
		
706
	    getStatus().setCpHpMp(getStatus().getMaxCp(), getStatus().getMaxHp(), getStatus().getMaxMp());
707
708
		_reviveRequested = 0;
709
		_revivePower = 0;
710
		
711
		if (isMounted())
712
			startFeed(_mountNpcId);
713
+	    if (isInsideZone(ZoneId.SOLO)) 
714
+	    {
715
+	        // Give Nobless (1323 ID)
716
+	        L2Skill no = SkillTable.getInstance().getInfo(1323, 1);
717
+	        no.getEffects(this, this);
718
+	        sendMessage("You have received the Nobless status in the Solo Zone.");
719
+	    }
720
+	}