SHOW:
|
|
- or go back to the newest paste.
1 | ### Eclipse Workspace Patch 1.0 | |
2 | #P L2jFrozen_GameServer | |
3 | Index: head-src/com/l2jfrozen/Config.java | |
4 | =================================================================== | |
5 | --- head-src/com/l2jfrozen/Config.java (nonexistent) | |
6 | +++ head-src/com/l2jfrozen/Config.java (working copy) | |
7 | ||
8 | import com.l2jfrozen.util.StringUtil; | |
9 | +import Base.Config.ExProperties; | |
10 | ||
11 | ||
12 | ||
13 | ||
14 | public final class Config | |
15 | { | |
16 | + public static final String DUNGEON_REWARD_FILE = "./events/Dungeon_Html_Reward.properties"; | |
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | ||
24 | e.printStackTrace(); | |
25 | throw new Error("Failed to Load " + OTHER + " File."); | |
26 | } | |
27 | } | |
28 | ||
29 | + public static ExProperties load(String filename) | |
30 | + { | |
31 | + return load(new File(filename)); | |
32 | + } | |
33 | + | |
34 | + public static ExProperties load(File file) | |
35 | + { | |
36 | + ExProperties result = new ExProperties(); | |
37 | + | |
38 | + try | |
39 | + { | |
40 | + result.load(file); | |
41 | + } | |
42 | + catch (IOException e) | |
43 | + { | |
44 | + LOGGER.warn("Error loading config : " + file.getName() + "!"); | |
45 | + } | |
46 | + | |
47 | + return result; | |
48 | + } | |
49 | // ============================================================ | |
50 | public static float RATE_XP; | |
51 | ||
52 | ||
53 | ||
54 | ||
55 | ||
56 | ||
57 | ||
58 | ||
59 | ||
60 | ||
61 | ||
62 | ||
63 | ||
64 | ||
65 | public static String PVP1_CUSTOM_MESSAGE; | |
66 | public static String PVP2_CUSTOM_MESSAGE; | |
67 | ||
68 | + public static int DUNGEON_COIN_ID; | |
69 | + public static int CONT_DUNGEON_ITEM; | |
70 | + public static int DUNGEON_SPAWN_X; | |
71 | + public static int DUNGEON_SPAWN_Y; | |
72 | + public static int DUNGEON_SPAWN_Z; | |
73 | + public static int DUNGEON_SPAWN_RND; | |
74 | ||
75 | + public static int DUNGEON_ITEM_RENEWAL0; | |
76 | + public static int DUNGEON_ITEM_RENEWAL1; | |
77 | + public static int DUNGEON_ITEM_RENEWAL2; | |
78 | + public static int DUNGEON_ITEM_RENEWAL3; | |
79 | + public static int DUNGEON_ITEM_RENEWAL4; | |
80 | + public static int DUNGEON_ITEM_RENEWAL5; | |
81 | + public static int DUNGEON_ITEM_RENEWAL6; | |
82 | + public static int DUNGEON_ITEM_RENEWAL7; | |
83 | + public static int DUNGEON_ITEM_RENEWAL8; | |
84 | + public static int DUNGEON_ITEM_RENEWAL9; | |
85 | + public static int DUNGEON_ITEM_RENEWAL10; | |
86 | ||
87 | ||
88 | ||
89 | ||
90 | ||
91 | ||
92 | ||
93 | ONLINE_PLAYERS_ON_LOGIN = Boolean.valueOf(L2JFrozenSettings.getProperty("OnlineOnLogin", "False")); | |
94 | SHOW_SERVER_VERSION = Boolean.valueOf(L2JFrozenSettings.getProperty("ShowServerVersion", "False")); | |
95 | ||
96 | ||
97 | ||
98 | + // Dungeon | |
99 | + ExProperties SafeDungeon = load(DUNGEON_REWARD_FILE); | |
100 | + | |
101 | + DUNGEON_COIN_ID = SafeDungeon.getProperty("DungeonCoinId", 57); | |
102 | + CONT_DUNGEON_ITEM = SafeDungeon.getProperty("DungeonContItem", 1); | |
103 | + DUNGEON_SPAWN_X = SafeDungeon.getProperty("DungeonSpawnX", 82635); | |
104 | + DUNGEON_SPAWN_Y = SafeDungeon.getProperty("DungeonSpawnY", 148798); | |
105 | + DUNGEON_SPAWN_Z = SafeDungeon.getProperty("DungeonSpawnZ", -3464); | |
106 | + DUNGEON_SPAWN_RND = SafeDungeon.getProperty("DungeonSpawnRnd", 25); | |
107 | + | |
108 | + DUNGEON_ITEM_RENEWAL0 = SafeDungeon.getProperty("DungeonRenewalHtml0", 15); | |
109 | + DUNGEON_ITEM_RENEWAL1 = SafeDungeon.getProperty("DungeonRenewalHtml1", 15); | |
110 | + DUNGEON_ITEM_RENEWAL2 = SafeDungeon.getProperty("DungeonRenewalHtml2", 15); | |
111 | + DUNGEON_ITEM_RENEWAL3 = SafeDungeon.getProperty("DungeonRenewalHtml3", 15); | |
112 | + DUNGEON_ITEM_RENEWAL4 = SafeDungeon.getProperty("DungeonRenewalHtml4", 15); | |
113 | + DUNGEON_ITEM_RENEWAL5 = SafeDungeon.getProperty("DungeonRenewalHtml5", 15); | |
114 | + DUNGEON_ITEM_RENEWAL6 = SafeDungeon.getProperty("DungeonRenewalHtml6", 15); | |
115 | + DUNGEON_ITEM_RENEWAL7 = SafeDungeon.getProperty("DungeonRenewalHtml7", 15); | |
116 | + DUNGEON_ITEM_RENEWAL8 = SafeDungeon.getProperty("DungeonRenewalHtml8", 15); | |
117 | + DUNGEON_ITEM_RENEWAL9 = SafeDungeon.getProperty("DungeonRenewalHtml9", 15); | |
118 | + DUNGEON_ITEM_RENEWAL10 = SafeDungeon.getProperty("DungeonRenewalHtml10", 15); | |
119 | ||
120 | ||
121 | ||
122 | ||
123 | ||
124 | ||
125 | ||
126 | ||
127 | ||
128 | ### Eclipse Workspace Patch 1.0 | |
129 | #P L2jFrozen_GameServer | |
130 | Index: head-src/Base/Dev/Dungeon/Dungeon.java | |
131 | =================================================================== | |
132 | --- head-src/Base/Dev/Dungeon/Dungeon.java (nonexistent) | |
133 | +++ head-src/Base/Dev/Dungeon/Dungeon.java (working copy) | |
134 | +/* | |
135 | + * This program is free software: you can redistribute it and/or modify it under | |
136 | + * the terms of the GNU General Public License as published by the Free Software | |
137 | + * Foundation, either version 3 of the License, or (at your option) any later | |
138 | + * version. | |
139 | +* | |
140 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
141 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
142 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
143 | + * details. | |
144 | + * | |
145 | + * You should have received a copy of the GNU General Public License along with | |
146 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
147 | + */ | |
148 | +package Base.Dev.Dungeon; | |
149 | + | |
150 | +import java.util.List; | |
151 | +import java.util.Map.Entry; | |
152 | +import java.util.concurrent.CopyOnWriteArrayList; | |
153 | +import java.util.concurrent.ScheduledFuture; | |
154 | + | |
155 | + | |
156 | +import com.l2jfrozen.Config; | |
157 | +import com.l2jfrozen.gameserver.datatables.sql.NpcTable; | |
158 | +import com.l2jfrozen.gameserver.datatables.sql.SpawnTable; | |
159 | +import com.l2jfrozen.gameserver.model.Location; | |
160 | +import com.l2jfrozen.gameserver.model.actor.instance.L2DungeonMobInstance; | |
161 | +import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance; | |
162 | +import com.l2jfrozen.gameserver.model.spawn.L2Spawn; | |
163 | +import com.l2jfrozen.gameserver.network.serverpackets.ExShowScreenMessage; | |
164 | +import com.l2jfrozen.gameserver.network.serverpackets.ExShowScreenMessage.SMPOS; | |
165 | +import com.l2jfrozen.gameserver.network.serverpackets.MagicSkillUser; | |
166 | +import com.l2jfrozen.gameserver.network.serverpackets.NpcHtmlMessage; | |
167 | +import com.l2jfrozen.gameserver.templates.L2NpcTemplate; | |
168 | +import com.l2jfrozen.gameserver.thread.ThreadPool; | |
169 | + | |
170 | +import Base.Memo.PlayerMemo; | |
171 | + | |
172 | + | |
173 | + | |
174 | +/** | |
175 | + * @author Anarchy | |
176 | + */ | |
177 | +public class Dungeon | |
178 | +{ | |
179 | + private DungeonTemplate template; | |
180 | + private List<L2PcInstance> players; | |
181 | + private ScheduledFuture<?> dungeonCancelTask = null; | |
182 | + private ScheduledFuture<?> nextTask = null; | |
183 | + private ScheduledFuture<?> timerTask = null; | |
184 | + private DungeonStage currentStage = null; | |
185 | + private long stageBeginTime = 0; | |
186 | + private List<L2DungeonMobInstance> mobs = new CopyOnWriteArrayList<>(); | |
187 | + private Instance instance; | |
188 | + | |
189 | + public Dungeon(DungeonTemplate template, List<L2PcInstance> players) | |
190 | + { | |
191 | + this.template = template; | |
192 | + this.players = players; | |
193 | + instance = InstanceManager.getInstance().createInstance(); | |
194 | + | |
195 | + for (L2PcInstance player : players) | |
196 | + player.setDungeon(this); | |
197 | + | |
198 | + beginTeleport(); | |
199 | + } | |
200 | + | |
201 | + public void onPlayerDeath(L2PcInstance player) | |
202 | + { | |
203 | + if (!players.contains(player)) | |
204 | + return; | |
205 | + | |
206 | + if (players.size() == 1) | |
207 | + ThreadPool.schedule(() -> cancelDungeon(), 5 * 1000); | |
208 | + else | |
209 | + player.sendMessage("You will be ressurected if your team completes this stage."); | |
210 | + } | |
211 | + | |
212 | + public synchronized void onMobKill(L2DungeonMobInstance mob) | |
213 | + { | |
214 | + if (!mobs.contains(mob)) | |
215 | + return; | |
216 | + | |
217 | + deleteMob(mob); | |
218 | + | |
219 | + if (mobs.isEmpty()) | |
220 | + { | |
221 | + if (dungeonCancelTask != null) | |
222 | + dungeonCancelTask.cancel(false); | |
223 | + if (timerTask != null) | |
224 | + timerTask.cancel(true); | |
225 | + if (nextTask != null) | |
226 | + nextTask.cancel(true); | |
227 | + | |
228 | + for (L2PcInstance player : players) | |
229 | + if (player.isDead()) | |
230 | + player.doRevive(); | |
231 | + | |
232 | + getNextStage(); | |
233 | + if (currentStage == null) // No more stages | |
234 | + { | |
235 | + rewardPlayers(); | |
236 | + if (template.getRewardHtm().equals("NULL")) | |
237 | + { | |
238 | + broadcastScreenMessage("You have completed the dungeon!", 5); | |
239 | + teleToTown(); | |
240 | + } | |
241 | + else | |
242 | + { | |
243 | + broadcastScreenMessage("You have completed the dungeon! Select your reward", 5); | |
244 | + // teleToTown(); | |
245 | + } | |
246 | + InstanceManager.getInstance().deleteInstance(instance.getId()); | |
247 | + DungeonManager.getInstance().removeDungeon(this); | |
248 | + } | |
249 | + else | |
250 | + { | |
251 | + broadcastScreenMessage("You have completed stage " + (currentStage.getOrder() - 1) + "! Next stage begins in 10 seconds.", 5); | |
252 | + ThreadPool.schedule(() -> teleToStage(), 5 * 1000); | |
253 | + nextTask = ThreadPool.schedule(() -> beginStage(), 10 * 1000); | |
254 | + } | |
255 | + } | |
256 | + } | |
257 | + | |
258 | + private void rewardPlayers() | |
259 | + { | |
260 | + // First Add Fixed Reward | |
261 | + for (L2PcInstance player : players) | |
262 | + { | |
263 | + | |
264 | + PlayerMemo.setVar(player, "dungeon_atleast1time", "true", -1); | |
265 | + for (Entry<Integer, Integer> itemId : template.getRewards().entrySet()) | |
266 | + { | |
267 | + player.addItem("dungeon reward", itemId.getKey(), itemId.getValue(), null, true); | |
268 | + } | |
269 | + } | |
270 | + | |
271 | + if (!template.getRewardHtm().equals("NULL")) | |
272 | + { | |
273 | + NpcHtmlMessage htm = new NpcHtmlMessage(0); | |
274 | + htm.setFile(template.getRewardHtm()); | |
275 | + for (L2PcInstance player : players) | |
276 | + player.sendPacket(htm); | |
277 | + } | |
278 | + else | |
279 | + { | |
280 | + for (L2PcInstance player : players) | |
281 | + { | |
282 | + player.setInstance(InstanceManager.getInstance().getInstance(0), true); | |
283 | + player.teleToLocation(Config.DUNGEON_SPAWN_X, Config.DUNGEON_SPAWN_Y, Config.DUNGEON_SPAWN_Z, Config.DUNGEON_SPAWN_RND); | |
284 | + } | |
285 | + } | |
286 | + } | |
287 | + | |
288 | + private void teleToStage() | |
289 | + { | |
290 | + if (!currentStage.teleport()) | |
291 | + return; | |
292 | + | |
293 | + for (L2PcInstance player : players) | |
294 | + player.teleToLocation(currentStage.getLocation(), 25); | |
295 | + } | |
296 | + | |
297 | + private void teleToTown() | |
298 | + { | |
299 | + for (L2PcInstance player : players) | |
300 | + { | |
301 | + if (!player.isOnline2() || player.getClient().isDetached()) | |
302 | + continue; | |
303 | + | |
304 | + DungeonManager.getInstance().getDungeonParticipants().remove(player.getObjectId()); | |
305 | + player.setDungeon(null); | |
306 | + player.setInstance(InstanceManager.getInstance().getInstance(0), true); | |
307 | + player.teleToLocation(Config.DUNGEON_SPAWN_X, Config.DUNGEON_SPAWN_Y, Config.DUNGEON_SPAWN_Z, Config.DUNGEON_SPAWN_RND); | |
308 | + } | |
309 | + } | |
310 | + | |
311 | + private void cancelDungeon() | |
312 | + { | |
313 | + for (L2PcInstance player : players) | |
314 | + { | |
315 | + if (player.isDead()) | |
316 | + player.doRevive(); | |
317 | + | |
318 | + player.abortAttack(); | |
319 | + player.abortCast(); | |
320 | + } | |
321 | + | |
322 | + | |
323 | + for (L2DungeonMobInstance mob : mobs) | |
324 | + deleteMob(mob); | |
325 | + | |
326 | + broadcastScreenMessage("You have failed to complete the dungeon. You will be teleported back in 10 seconds.", 5); | |
327 | + teleToTown(); | |
328 | + | |
329 | + InstanceManager.getInstance().deleteInstance(instance.getId()); | |
330 | + DungeonManager.getInstance().removeDungeon(this); | |
331 | + | |
332 | + if (nextTask != null) | |
333 | + nextTask.cancel(true); | |
334 | + if (timerTask != null) | |
335 | + timerTask.cancel(true); | |
336 | + if (dungeonCancelTask != null) | |
337 | + dungeonCancelTask.cancel(true); | |
338 | + } | |
339 | + | |
340 | + private void deleteMob(L2DungeonMobInstance mob) | |
341 | + { | |
342 | + if (!mobs.contains(mob)) | |
343 | + return; | |
344 | + | |
345 | + mobs.remove(mob); | |
346 | + if (mob.getSpawn() != null) | |
347 | + SpawnTable.getInstance().deleteSpawn(mob.getSpawn(), false); | |
348 | + mob.deleteMe(); | |
349 | + } | |
350 | + | |
351 | + private void beginStage() | |
352 | + { | |
353 | + for (int mobId : currentStage.getMobs().keySet()) | |
354 | + spawnMob(mobId, currentStage.getMobs().get(mobId)); | |
355 | + | |
356 | + stageBeginTime = System.currentTimeMillis(); | |
357 | + timerTask = ThreadPool.scheduleAtFixedRate(() -> broadcastTimer(), 5 * 1000, 1000); | |
358 | + nextTask = null; | |
359 | + dungeonCancelTask = ThreadPool.schedule(() -> cancelDungeon(), 1000 * 60 * currentStage.getMinutes()); | |
360 | + broadcastScreenMessage("You have " + currentStage.getMinutes() + " minutes to finish stage " + currentStage.getOrder() + "!", 5); | |
361 | + } | |
362 | + | |
363 | + private void spawnMob(int mobId, List<Location> locations) | |
364 | + { | |
365 | + L2NpcTemplate template = NpcTable.getInstance().getTemplate(mobId); | |
366 | + try | |
367 | + { | |
368 | + for (Location loc : locations) | |
369 | + { | |
370 | + L2Spawn spawn = new L2Spawn(template); | |
371 | + spawn.setLocx(loc.getX()); | |
372 | + spawn.setLocy(loc.getY()); | |
373 | + spawn.setLocz(loc.getZ()); | |
374 | + | |
375 | + spawn.setRespawnDelay(1); | |
376 | + spawn.doSpawn(false); | |
377 | + | |
378 | + ((L2DungeonMobInstance) spawn.getNpc()).setDungeon(this); | |
379 | + spawn.getNpc().setInstance(instance, false); // Set instance first | |
380 | + // SpawnTable.getInstance().addNewSpawn(spawn, false); // TODO: Useless | |
381 | + spawn.getNpc().broadcastStatusUpdate(); | |
382 | + | |
383 | + // Add it to memory | |
384 | + mobs.add((L2DungeonMobInstance) spawn.getNpc()); | |
385 | + } | |
386 | + } | |
387 | + catch (Exception e) | |
388 | + { | |
389 | + e.printStackTrace(); | |
390 | + } | |
391 | + } | |
392 | + | |
393 | + private void teleportPlayers() | |
394 | + { | |
395 | + for (L2PcInstance player : players) | |
396 | + player.setInstance(instance, true); | |
397 | + | |
398 | + teleToStage(); | |
399 | + | |
400 | + broadcastScreenMessage("Stage " + currentStage.getOrder() + " begins in 10 seconds!", 5); | |
401 | + | |
402 | + nextTask = ThreadPool.schedule(() -> beginStage(), 10 * 1000); | |
403 | + } | |
404 | + | |
405 | + private void beginTeleport() | |
406 | + { | |
407 | + getNextStage(); | |
408 | + for (L2PcInstance player : players) | |
409 | + { | |
410 | + player.broadcastPacket(new MagicSkillUser(player, 1050, 1, 10000, 10000)); | |
411 | + broadcastScreenMessage("You will be teleported in 10 seconds!", 3); | |
412 | + } | |
413 | + | |
414 | + nextTask = ThreadPool.schedule(() -> teleportPlayers(), 10 * 1000); | |
415 | + } | |
416 | + | |
417 | + private void getNextStage() | |
418 | + { | |
419 | + currentStage = currentStage == null ? template.getStages().get(1) : template.getStages().get(currentStage.getOrder() + 1); | |
420 | + } | |
421 | + | |
422 | + private void broadcastTimer() | |
423 | + { | |
424 | + int secondsLeft = (int) (((stageBeginTime + (1000 * 60 * currentStage.getMinutes())) - System.currentTimeMillis()) / 1000); | |
425 | + int minutes = secondsLeft / 60; | |
426 | + int seconds = secondsLeft % 60; | |
427 | + ExShowScreenMessage packet = new ExShowScreenMessage(String.format("%02d:%02d", minutes, seconds), 1010, SMPOS.BOTTOM_RIGHT, false); | |
428 | + for (L2PcInstance player : players) | |
429 | + player.sendPacket(packet); | |
430 | + } | |
431 | + | |
432 | + private void broadcastScreenMessage(String msg, int seconds) | |
433 | + { | |
434 | + ExShowScreenMessage packet = new ExShowScreenMessage(msg, seconds * 1000, SMPOS.TOP_CENTER, false); | |
435 | + for (L2PcInstance player : players) | |
436 | + player.sendPacket(packet); | |
437 | + } | |
438 | + | |
439 | + public List<L2PcInstance> getPlayers() | |
440 | + { | |
441 | + return players; | |
442 | + } | |
443 | +} | |
444 | ||
445 | ### Eclipse Workspace Patch 1.0 | |
446 | #P L2jFrozen_GameServer | |
447 | Index: head-src/Base/Dev/Dungeon/DungeonManager.java | |
448 | =================================================================== | |
449 | --- head-src/Base/Dev/Dungeon/DungeonManager.java (nonexistent) | |
450 | +++ head-src/Base/Dev/Dungeon/DungeonManager.java (working copy) | |
451 | +/* | |
452 | + * This program is free software: you can redistribute it and/or modify it under | |
453 | + * the terms of the GNU General Public License as published by the Free Software | |
454 | + * Foundation, either version 3 of the License, or (at your option) any later | |
455 | + * version. | |
456 | + * | |
457 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
458 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
459 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
460 | + * details. | |
461 | + * | |
462 | + * You should have received a copy of the GNU General Public License along with | |
463 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
464 | + */ | |
465 | +package Base.Dev.Dungeon; | |
466 | + | |
467 | +import java.io.File; | |
468 | +import java.sql.Connection; | |
469 | +import java.sql.PreparedStatement; | |
470 | +import java.sql.ResultSet; | |
471 | +import java.util.ArrayList; | |
472 | +import java.util.HashMap; | |
473 | +import java.util.List; | |
474 | +import java.util.Map; | |
475 | +import java.util.concurrent.ConcurrentHashMap; | |
476 | +import java.util.concurrent.CopyOnWriteArrayList; | |
477 | +import java.util.logging.Level; | |
478 | +import java.util.logging.Logger; | |
479 | + | |
480 | + | |
481 | + | |
482 | +import org.w3c.dom.Document; | |
483 | +import org.w3c.dom.NamedNodeMap; | |
484 | +import org.w3c.dom.Node; | |
485 | + | |
486 | +import com.l2jfrozen.gameserver.model.Location; | |
487 | +import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance; | |
488 | +import com.l2jfrozen.gameserver.thread.ThreadPool; | |
489 | +import com.l2jfrozen.util.database.L2DatabaseFactory; | |
490 | + | |
491 | +import Base.XML.XMLDocumentFactory; | |
492 | + | |
493 | +/** | |
494 | + * @author Juvenil Walker | |
495 | + */ | |
496 | +public class DungeonManager | |
497 | +{ | |
498 | + private static Logger log = Logger.getLogger(DungeonManager.class.getName()); | |
499 | + | |
500 | + private Map<Integer, DungeonTemplate> templates; | |
501 | + private List<Dungeon> running; | |
502 | + private List<Integer> dungeonParticipants; | |
503 | + private boolean reloading = false; | |
504 | + private Map<String, Long[]> dungeonPlayerData; | |
505 | + | |
506 | + protected DungeonManager() | |
507 | + { | |
508 | + templates = new ConcurrentHashMap<>(); | |
509 | + running = new CopyOnWriteArrayList<>(); | |
510 | + dungeonParticipants = new CopyOnWriteArrayList<>(); | |
511 | + dungeonPlayerData = new ConcurrentHashMap<>(); | |
512 | + | |
513 | + load(); | |
514 | + ThreadPool.scheduleAtFixedRate(() -> updateDatabase(), 1000 * 60 * 30, 1000 * 60 * 60); | |
515 | + } | |
516 | + | |
517 | + private void updateDatabase() | |
518 | + { | |
519 | + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) | |
520 | + { | |
521 | + PreparedStatement stm = con.prepareStatement("DELETE FROM dungeon"); | |
522 | + stm.execute(); | |
523 | + | |
524 | + for (String ip : dungeonPlayerData.keySet()) | |
525 | + { | |
526 | + for (int i = 1; i < dungeonPlayerData.get(ip).length; i++) | |
527 | + { | |
528 | + PreparedStatement stm2 = con.prepareStatement("INSERT INTO dungeon VALUES (?,?,?)"); | |
529 | + stm2.setInt(1, i); | |
530 | + stm2.setString(2, ip); | |
531 | + stm2.setLong(3, dungeonPlayerData.get(ip)[i]); | |
532 | + stm2.execute(); | |
533 | + stm2.close(); | |
534 | + } | |
535 | + } | |
536 | + | |
537 | + stm.close(); | |
538 | + } | |
539 | + catch (Exception e) | |
540 | + { | |
541 | + e.printStackTrace(); | |
542 | + } | |
543 | + } | |
544 | + | |
545 | + public boolean reload() | |
546 | + { | |
547 | + if (!running.isEmpty()) | |
548 | + { | |
549 | + reloading = true; | |
550 | + return false; | |
551 | + } | |
552 | + | |
553 | + templates.clear(); | |
554 | + load(); | |
555 | + return true; | |
556 | + } | |
557 | + | |
558 | + private void load() | |
559 | + { | |
560 | + try | |
561 | + { | |
562 | + File f = new File("./events/Dungeon.xml"); | |
563 | + Document doc = XMLDocumentFactory.getInstance().loadDocument(f); | |
564 | + | |
565 | + Node n = doc.getFirstChild(); | |
566 | + for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) | |
567 | + { | |
568 | + if (d.getNodeName().equals("dungeon")) | |
569 | + { | |
570 | + int id = Integer.parseInt(d.getAttributes().getNamedItem("id").getNodeValue()); | |
571 | + String name = d.getAttributes().getNamedItem("name").getNodeValue(); | |
572 | + int players = Integer.parseInt(d.getAttributes().getNamedItem("players").getNodeValue()); | |
573 | + Map<Integer, Integer> rewards = new HashMap<>(); | |
574 | + String rewardHtm = d.getAttributes().getNamedItem("rewardHtm").getNodeValue(); | |
575 | + Map<Integer, DungeonStage> stages = new HashMap<>(); | |
576 | + | |
577 | + String rewards_data = d.getAttributes().getNamedItem("rewards").getNodeValue(); | |
578 | + if (!rewards_data.isEmpty()) // If config is empty do not feed the rewards | |
579 | + { | |
580 | + String[] rewards_data_split = rewards_data.split(";"); | |
581 | + for (String reward : rewards_data_split) | |
582 | + { | |
583 | + String[] reward_split = reward.split(","); | |
584 | + rewards.put(Integer.parseInt(reward_split[0]), Integer.parseInt(reward_split[1])); | |
585 | + } | |
586 | + } | |
587 | + | |
588 | + for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling()) | |
589 | + { | |
590 | + NamedNodeMap attrs = cd.getAttributes(); | |
591 | + | |
592 | + if (cd.getNodeName().equals("stage")) | |
593 | + { | |
594 | + int order = Integer.parseInt(attrs.getNamedItem("order").getNodeValue()); | |
595 | + String loc_data = attrs.getNamedItem("loc").getNodeValue(); | |
596 | + String[] loc_data_split = loc_data.split(","); | |
597 | + Location loc = new Location(Integer.parseInt(loc_data_split[0]), Integer.parseInt(loc_data_split[1]), Integer.parseInt(loc_data_split[2])); | |
598 | + boolean teleport = Boolean.parseBoolean(attrs.getNamedItem("teleport").getNodeValue()); | |
599 | + int minutes = Integer.parseInt(attrs.getNamedItem("minutes").getNodeValue()); | |
600 | + Map<Integer, List<Location>> mobs = new HashMap<>(); | |
601 | + | |
602 | + for (Node ccd = cd.getFirstChild(); ccd != null; ccd = ccd.getNextSibling()) | |
603 | + { | |
604 | + NamedNodeMap attrs2 = ccd.getAttributes(); | |
605 | + | |
606 | + if (ccd.getNodeName().equals("mob")) | |
607 | + { | |
608 | + int npcId = Integer.parseInt(attrs2.getNamedItem("npcId").getNodeValue()); | |
609 | + List<Location> locs = new ArrayList<>(); | |
610 | + | |
611 | + String locs_data = attrs2.getNamedItem("locs").getNodeValue(); | |
612 | + String[] locs_data_split = locs_data.split(";"); | |
613 | + for (String locc : locs_data_split) | |
614 | + { | |
615 | + String[] locc_data = locc.split(","); | |
616 | + locs.add(new Location(Integer.parseInt(locc_data[0]), Integer.parseInt(locc_data[1]), Integer.parseInt(locc_data[2]))); | |
617 | + } | |
618 | + | |
619 | + mobs.put(npcId, locs); | |
620 | + } | |
621 | + } | |
622 | + | |
623 | + stages.put(order, new DungeonStage(order, loc, teleport, minutes, mobs)); | |
624 | + } | |
625 | + } | |
626 | + | |
627 | + templates.put(id, new DungeonTemplate(id, name, players, rewards, rewardHtm, stages)); | |
628 | + } | |
629 | + } | |
630 | + } | |
631 | + catch (Exception e) | |
632 | + { | |
633 | + log.log(Level.WARNING, "DungeonManager: Error loading dungeons.xml", e); | |
634 | + e.printStackTrace(); | |
635 | + } | |
636 | + | |
637 | + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) | |
638 | + { | |
639 | + PreparedStatement stm = con.prepareStatement("SELECT * FROM dungeon"); | |
640 | + ResultSet rset = stm.executeQuery(); | |
641 | + | |
642 | + while (rset.next()) | |
643 | + { | |
644 | + int dungid = rset.getInt("dungid"); | |
645 | + String ipaddr = rset.getString("ipaddr"); | |
646 | + long lastjoin = rset.getLong("lastjoin"); | |
647 | + | |
648 | + if (!dungeonPlayerData.containsKey(ipaddr)) | |
649 | + { | |
650 | + Long[] times = new Long[templates.size() + 1]; | |
651 | + for (int i = 0; i < times.length; i++) | |
652 | + times[i] = 0L; | |
653 | + times[dungid] = lastjoin; | |
654 | + | |
655 | + dungeonPlayerData.put(ipaddr, times); | |
656 | + } | |
657 | + else | |
658 | + dungeonPlayerData.get(ipaddr)[dungid] = lastjoin; | |
659 | + } | |
660 | + | |
661 | + rset.close(); | |
662 | + stm.close(); | |
663 | + } | |
664 | + catch (Exception e) | |
665 | + { | |
666 | + e.printStackTrace(); | |
667 | + } | |
668 | + | |
669 | + log.info("DungeonManager: Loaded " + templates.size() + " dungeon templates"); | |
670 | + } | |
671 | + | |
672 | + public synchronized void removeDungeon(Dungeon dungeon) | |
673 | + { | |
674 | + running.remove(dungeon); | |
675 | + | |
676 | + if (reloading && running.isEmpty()) | |
677 | + { | |
678 | + reloading = false; | |
679 | + reload(); | |
680 | + } | |
681 | + } | |
682 | + | |
683 | + public synchronized void enterDungeon(int id, L2PcInstance player) | |
684 | + { | |
685 | + if (reloading) | |
686 | + { | |
687 | + player.sendMessage("The Dungeon system is reloading, please try again in a few minutes."); | |
688 | + return; | |
689 | + } | |
690 | + | |
691 | + DungeonTemplate template = templates.get(id); | |
692 | + if (template.getPlayers() > 1 && (!player.isInParty() || player.getParty().getMemberCount() != template.getPlayers())) | |
693 | + { | |
694 | + player.sendMessage("You need a party of " + template.getPlayers() + " players to enter this Dungeon."); | |
695 | + return; | |
696 | + } | |
697 | + else if (template.getPlayers() == 1 && player.isInParty()) | |
698 | + { | |
699 | + player.sendMessage("You can only enter this Dungeon alone."); | |
700 | + return; | |
701 | + } | |
702 | + | |
703 | + List<L2PcInstance> players = new ArrayList<>(); | |
704 | + if (player.isInParty()) | |
705 | + { | |
706 | + for (L2PcInstance pm : player.getParty().getPartyMembers()) | |
707 | + { | |
708 | + String pmip = pm.getIP(); | |
709 | + if (dungeonPlayerData.containsKey(pmip) && (System.currentTimeMillis() - dungeonPlayerData.get(pmip)[template.getId()] < 1000 * 60 * 60 * 24)) | |
710 | + { | |
711 | + player.sendMessage("One of your party members cannot join this Dungeon because 24 hours have not passed since they last joined."); | |
712 | + return; | |
713 | + } | |
714 | + } | |
715 | + | |
716 | + for (L2PcInstance pm : player.getParty().getPartyMembers()) | |
717 | + { | |
718 | + String pmip = pm.getIP(); | |
719 | + | |
720 | + dungeonParticipants.add(pm.getObjectId()); | |
721 | + players.add(pm); | |
722 | + if (dungeonPlayerData.containsKey(pmip)) | |
723 | + dungeonPlayerData.get(pmip)[template.getId()] = System.currentTimeMillis(); | |
724 | + else | |
725 | + { | |
726 | + Long[] times = new Long[templates.size() + 1]; | |
727 | + for (int i = 0; i < times.length; i++) | |
728 | + times[i] = 0L; | |
729 | + times[template.getId()] = System.currentTimeMillis(); | |
730 | + dungeonPlayerData.put(pmip, times); | |
731 | + } | |
732 | + } | |
733 | + } | |
734 | + else | |
735 | + { | |
736 | + String pmip = player.getIP(); | |
737 | + if (dungeonPlayerData.containsKey(pmip) && (System.currentTimeMillis() - dungeonPlayerData.get(pmip)[template.getId()] < 1000 * 60 * 60 * 24)) | |
738 | + { | |
739 | + player.sendMessage("24 hours have not passed since you last entered this Dungeon."); | |
740 | + return; | |
741 | + } | |
742 | + | |
743 | + dungeonParticipants.add(player.getObjectId()); | |
744 | + players.add(player); | |
745 | + if (dungeonPlayerData.containsKey(pmip)) | |
746 | + dungeonPlayerData.get(pmip)[template.getId()] = System.currentTimeMillis(); | |
747 | + else | |
748 | + { | |
749 | + Long[] times = new Long[templates.size() + 1]; | |
750 | + for (int i = 0; i < times.length; i++) | |
751 | + times[i] = 0L; | |
752 | + times[template.getId()] = System.currentTimeMillis(); | |
753 | + dungeonPlayerData.put(pmip, times); | |
754 | + } | |
755 | + } | |
756 | + | |
757 | + running.add(new Dungeon(template, players)); | |
758 | + } | |
759 | + | |
760 | + public boolean isReloading() | |
761 | + { | |
762 | + return reloading; | |
763 | + } | |
764 | + | |
765 | + public boolean isInDungeon(L2PcInstance player) | |
766 | + { | |
767 | + for (Dungeon dungeon : running) | |
768 | + for (L2PcInstance p : dungeon.getPlayers()) | |
769 | + if (p == player) | |
770 | + return true; | |
771 | + | |
772 | + return false; | |
773 | + } | |
774 | + | |
775 | + public Map<String, Long[]> getPlayerData() | |
776 | + { | |
777 | + return dungeonPlayerData; | |
778 | + } | |
779 | + | |
780 | + public List<Integer> getDungeonParticipants() | |
781 | + { | |
782 | + return dungeonParticipants; | |
783 | + } | |
784 | + | |
785 | + public static DungeonManager getInstance() | |
786 | + { | |
787 | + return SingletonHolder.instance; | |
788 | + } | |
789 | + | |
790 | + private static class SingletonHolder | |
791 | + { | |
792 | + protected static final DungeonManager instance = new DungeonManager(); | |
793 | + } | |
794 | +} | |
795 | ||
796 | ### Eclipse Workspace Patch 1.0 | |
797 | #P L2jFrozen_GameServer | |
798 | Index: head-src/Base/Dev/Dungeon/DungeonStage.java | |
799 | =================================================================== | |
800 | --- head-src/Base/Dev/Dungeon/DungeonStage.java (nonexistent) | |
801 | +++ head-src/Base/Dev/Dungeon/DungeonStage.java (working copy) | |
802 | +/* | |
803 | + * This program is free software: you can redistribute it and/or modify it under | |
804 | + * the terms of the GNU General Public License as published by the Free Software | |
805 | + * Foundation, either version 3 of the License, or (at your option) any later | |
806 | + * version. | |
807 | + * | |
808 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
809 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
810 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
811 | + * details. | |
812 | + * | |
813 | + * You should have received a copy of the GNU General Public License along with | |
814 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
815 | + */ | |
816 | +package Base.Dev.Dungeon; | |
817 | + | |
818 | +import java.util.List; | |
819 | +import java.util.Map; | |
820 | + | |
821 | +import com.l2jfrozen.gameserver.model.Location; | |
822 | + | |
823 | + | |
824 | +/** | |
825 | + * @author Anarchy | |
826 | + * | |
827 | + */ | |
828 | +public class DungeonStage | |
829 | +{ | |
830 | + private int order; | |
831 | + private Location location; | |
832 | + private boolean teleport; | |
833 | + private int minutes; | |
834 | + private Map<Integer, List<Location>> mobs; | |
835 | + | |
836 | + public DungeonStage(int order, Location location, boolean teleport, int minutes, Map<Integer, List<Location>> mobs) | |
837 | + { | |
838 | + this.order = order; | |
839 | + this.location = location; | |
840 | + this.teleport = teleport; | |
841 | + this.minutes = minutes; | |
842 | + this.mobs = mobs; | |
843 | + } | |
844 | + | |
845 | + public int getOrder() | |
846 | + { | |
847 | + return order; | |
848 | + } | |
849 | + | |
850 | + public Location getLocation() | |
851 | + { | |
852 | + return location; | |
853 | + } | |
854 | + | |
855 | + public boolean teleport() | |
856 | + { | |
857 | + return teleport; | |
858 | + } | |
859 | + | |
860 | + public int getMinutes() | |
861 | + { | |
862 | + return minutes; | |
863 | + } | |
864 | + | |
865 | + public Map<Integer, List<Location>> getMobs() | |
866 | + { | |
867 | + return mobs; | |
868 | + } | |
869 | +} | |
870 | ||
871 | ### Eclipse Workspace Patch 1.0 | |
872 | #P L2jFrozen_GameServer | |
873 | Index: head-src/Base/Dev/Dungeon/DungeonTemplate.java | |
874 | =================================================================== | |
875 | --- head-src/Base/Dev/Dungeon/DungeonTemplate.java (nonexistent) | |
876 | +++ head-src/Base/Dev/Dungeon/DungeonTemplate.java (working copy) | |
877 | +/* | |
878 | + * This program is free software: you can redistribute it and/or modify it under | |
879 | + * the terms of the GNU General Public License as published by the Free Software | |
880 | + * Foundation, either version 3 of the License, or (at your option) any later | |
881 | + * version. | |
882 | + * | |
883 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
884 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
885 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
886 | + * details. | |
887 | + * | |
888 | + * You should have received a copy of the GNU General Public License along with | |
889 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
890 | + */ | |
891 | +package Base.Dev.Dungeon; | |
892 | + | |
893 | +import java.util.Map; | |
894 | + | |
895 | +/** | |
896 | + * @author Anarchy | |
897 | + * | |
898 | + */ | |
899 | +public class DungeonTemplate | |
900 | +{ | |
901 | + private int id; | |
902 | + private String name; | |
903 | + private int players; | |
904 | + private Map<Integer, Integer> rewards; | |
905 | + private String rewardHtm; | |
906 | + private Map<Integer, DungeonStage> stages; | |
907 | + | |
908 | + public DungeonTemplate(int id, String name, int players, Map<Integer, Integer> rewards, String rewardHtm, Map<Integer, DungeonStage> stages) | |
909 | + { | |
910 | + this.id = id; | |
911 | + this.name = name; | |
912 | + this.players = players; | |
913 | + this.rewards = rewards; | |
914 | + this.rewardHtm = rewardHtm; | |
915 | + this.stages = stages; | |
916 | + } | |
917 | + | |
918 | + public int getId() | |
919 | + { | |
920 | + return id; | |
921 | + } | |
922 | + | |
923 | + public String getName() | |
924 | + { | |
925 | + return name; | |
926 | + } | |
927 | + | |
928 | + public int getPlayers() | |
929 | + { | |
930 | + return players; | |
931 | + } | |
932 | + | |
933 | + public Map<Integer, Integer> getRewards() | |
934 | + { | |
935 | + return rewards; | |
936 | + } | |
937 | + | |
938 | + public String getRewardHtm() | |
939 | + { | |
940 | + return rewardHtm; | |
941 | + } | |
942 | + | |
943 | + public Map<Integer, DungeonStage> getStages() | |
944 | + { | |
945 | + return stages; | |
946 | + } | |
947 | +} | |
948 | ||
949 | ### Eclipse Workspace Patch 1.0 | |
950 | #P L2jFrozen_GameServer | |
951 | Index: head-src/Base/Dev/Dungeon/Instance.java | |
952 | =================================================================== | |
953 | --- head-src/Base/Dev/Dungeon/Instance.java (nonexistent) | |
954 | +++ head-src/Base/Dev/Dungeon/Instance.java (working copy) | |
955 | +/* | |
956 | + * This program is free software: you can redistribute it and/or modify it under | |
957 | + * the terms of the GNU General Public License as published by the Free Software | |
958 | + * Foundation, either version 3 of the License, or (at your option) any later | |
959 | + * version. | |
960 | + * | |
961 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
962 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
963 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
964 | + * details. | |
965 | + * | |
966 | + * You should have received a copy of the GNU General Public License along with | |
967 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
968 | + */ | |
969 | +package Base.Dev.Dungeon; | |
970 | + | |
971 | +import java.util.ArrayList; | |
972 | +import java.util.List; | |
973 | + | |
974 | +import com.l2jfrozen.gameserver.model.actor.instance.L2DoorInstance; | |
975 | + | |
976 | + | |
977 | + | |
978 | +/** | |
979 | + * @author Anarchy | |
980 | + * | |
981 | + */ | |
982 | +public class Instance | |
983 | +{ | |
984 | + private int id; | |
985 | + private List<L2DoorInstance> doors; | |
986 | + | |
987 | + public Instance(int id) | |
988 | + { | |
989 | + this.id = id; | |
990 | + doors = new ArrayList<>(); | |
991 | + } | |
992 | + | |
993 | + public void openDoors() | |
994 | + { | |
995 | + for (L2DoorInstance door : doors) | |
996 | + door.openMe(); | |
997 | + } | |
998 | + | |
999 | + public void closeDoors() | |
1000 | + { | |
1001 | + for (L2DoorInstance door : doors) | |
1002 | + door.closeMe(); | |
1003 | + } | |
1004 | + | |
1005 | + public void addDoor(L2DoorInstance door) | |
1006 | + { | |
1007 | + doors.add(door); | |
1008 | + } | |
1009 | + | |
1010 | + public List<L2DoorInstance> getDoors() | |
1011 | + { | |
1012 | + return doors; | |
1013 | + } | |
1014 | + | |
1015 | + public int getId() | |
1016 | + { | |
1017 | + return id; | |
1018 | + } | |
1019 | +} | |
1020 | ||
1021 | ### Eclipse Workspace Patch 1.0 | |
1022 | #P L2jFrozen_GameServer | |
1023 | Index: head-src/Base/Dev/Dungeon/InstanceIdFactory.java | |
1024 | =================================================================== | |
1025 | --- head-src/Base/Dev/Dungeon/InstanceIdFactory.java (nonexistent) | |
1026 | +++ head-src/Base/Dev/Dungeon/InstanceIdFactory.java (working copy) | |
1027 | +/* | |
1028 | + * This program is free software: you can redistribute it and/or modify it under | |
1029 | + * the terms of the GNU General Public License as published by the Free Software | |
1030 | + * Foundation, either version 3 of the License, or (at your option) any later | |
1031 | + * version. | |
1032 | + * | |
1033 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
1034 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
1035 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
1036 | + * details. | |
1037 | + * | |
1038 | + * You should have received a copy of the GNU General Public License along with | |
1039 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
1040 | + */ | |
1041 | +package Base.Dev.Dungeon; | |
1042 | + | |
1043 | +import java.util.concurrent.atomic.AtomicInteger; | |
1044 | + | |
1045 | +/** | |
1046 | + * @author Anarchy | |
1047 | + * | |
1048 | + */ | |
1049 | +public final class InstanceIdFactory | |
1050 | +{ | |
1051 | + private static AtomicInteger nextAvailable = new AtomicInteger(1); | |
1052 | + | |
1053 | + public synchronized static int getNextAvailable() | |
1054 | + { | |
1055 | + return nextAvailable.getAndIncrement(); | |
1056 | + } | |
1057 | +} | |
1058 | ||
1059 | ||
1060 | ### Eclipse Workspace Patch 1.0 | |
1061 | #P L2jFrozen_GameServer | |
1062 | Index: head-src/Base/Dev/Dungeon/InstanceManager.java | |
1063 | =================================================================== | |
1064 | --- head-src/Base/Dev/Dungeon/InstanceManager.java (nonexistent) | |
1065 | +++ head-src/Base/Dev/Dungeon/InstanceManager.java (working copy) | |
1066 | +/* | |
1067 | + * This program is free software: you can redistribute it and/or modify it under | |
1068 | + * the terms of the GNU General Public License as published by the Free Software | |
1069 | + * Foundation, either version 3 of the License, or (at your option) any later | |
1070 | + * version. | |
1071 | + * | |
1072 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
1073 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
1074 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
1075 | + * details. | |
1076 | + * | |
1077 | + * You should have received a copy of the GNU General Public License along with | |
1078 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
1079 | + */ | |
1080 | +package Base.Dev.Dungeon; | |
1081 | + | |
1082 | +import java.util.Map; | |
1083 | +import java.util.concurrent.ConcurrentHashMap; | |
1084 | + | |
1085 | +import com.l2jfrozen.gameserver.model.actor.instance.L2DoorInstance; | |
1086 | + | |
1087 | + | |
1088 | + | |
1089 | +/** | |
1090 | + * @author Anarchy | |
1091 | + * | |
1092 | + */ | |
1093 | +public class InstanceManager | |
1094 | +{ | |
1095 | + private Map<Integer, Instance> instances; | |
1096 | + | |
1097 | + protected InstanceManager() | |
1098 | + { | |
1099 | + instances = new ConcurrentHashMap<>(); | |
1100 | + instances.put(0, new Instance(0)); | |
1101 | + } | |
1102 | + | |
1103 | + public void addDoor(int id, L2DoorInstance door) | |
1104 | + { | |
1105 | + if (!instances.containsKey(id) || id == 0) | |
1106 | + return; | |
1107 | + | |
1108 | + instances.get(id).addDoor(door); | |
1109 | + } | |
1110 | + | |
1111 | + public void deleteInstance(int id) | |
1112 | + { | |
1113 | + if (id == 0) | |
1114 | + { | |
1115 | + System.out.println("Attempt to delete instance with id 0."); | |
1116 | + return; | |
1117 | + } | |
1118 | + | |
1119 | + // delete doors | |
1120 | + } | |
1121 | + | |
1122 | + public synchronized Instance createInstance() | |
1123 | + { | |
1124 | + Instance instance = new Instance(InstanceIdFactory.getNextAvailable()); | |
1125 | + instances.put(instance.getId(), instance); | |
1126 | + return instance; | |
1127 | + } | |
1128 | + | |
1129 | + public Instance getInstance(int id) | |
1130 | + { | |
1131 | + return instances.get(id); | |
1132 | + } | |
1133 | + | |
1134 | + public static InstanceManager getInstance() | |
1135 | + { | |
1136 | + return SingletonHolder.instance; | |
1137 | + } | |
1138 | + | |
1139 | + private static final class SingletonHolder | |
1140 | + { | |
1141 | + protected static final InstanceManager instance = new InstanceManager(); | |
1142 | + } | |
1143 | +} | |
1144 | ||
1145 | ### Eclipse Workspace Patch 1.0 | |
1146 | #P L2jFrozen_GameServer | |
1147 | Index: head-src/Base/Manager/NewCharTaskManager.java | |
1148 | =================================================================== | |
1149 | --- head-src/Base/Manager/NewCharTaskManager.java (nonexistent) | |
1150 | +++ head-src/Base/Manager/NewCharTaskManager.java (working copy) | |
1151 | +package Base.Manager; | |
1152 | + | |
1153 | +import java.util.Map; | |
1154 | +import java.util.concurrent.ConcurrentHashMap; | |
1155 | + | |
1156 | +import com.l2jfrozen.gameserver.model.L2Character; | |
1157 | +import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance; | |
1158 | +import com.l2jfrozen.gameserver.thread.ThreadPool; | |
1159 | + | |
1160 | + | |
1161 | +/** | |
1162 | + * @author Baggos | |
1163 | + */ | |
1164 | +public final class NewCharTaskManager implements Runnable | |
1165 | +{ | |
1166 | + private final Map<L2PcInstance, Long> _players = new ConcurrentHashMap<>(); | |
1167 | + | |
1168 | + protected NewCharTaskManager() | |
1169 | + { | |
1170 | + // Run task each 10 second. | |
1171 | + ThreadPool.scheduleAtFixedRate(this, 1000, 1000); | |
1172 | + } | |
1173 | + | |
1174 | + public final void add(L2PcInstance player) | |
1175 | + { | |
1176 | + _players.put(player, System.currentTimeMillis()); | |
1177 | + } | |
1178 | + | |
1179 | + public final void remove(L2Character player) | |
1180 | + { | |
1181 | + _players.remove(player); | |
1182 | + } | |
1183 | + | |
1184 | + @Override | |
1185 | + public final void run() | |
1186 | + { | |
1187 | + if (_players.isEmpty()) | |
1188 | + return; | |
1189 | + | |
1190 | + for (Map.Entry<L2PcInstance, Long> entry : _players.entrySet()) | |
1191 | + { | |
1192 | + final L2PcInstance player = entry.getKey(); | |
1193 | + | |
1194 | + if (player.getMemos().getLong("newEndTime") < System.currentTimeMillis()) | |
1195 | + { | |
1196 | + L2PcInstance.removeNewChar(player); | |
1197 | + remove(player); | |
1198 | + } | |
1199 | + } | |
1200 | + } | |
1201 | + | |
1202 | + public static final NewCharTaskManager getInstance() | |
1203 | + { | |
1204 | + return SingletonHolder._instance; | |
1205 | + } | |
1206 | + | |
1207 | + private static class SingletonHolder | |
1208 | + { | |
1209 | + protected static final NewCharTaskManager _instance = new NewCharTaskManager(); | |
1210 | + } | |
1211 | +} | |
1212 | ||
1213 | ### Eclipse Workspace Patch 1.0 | |
1214 | #P L2jFrozen_GameServer | |
1215 | Index: head-src/Base/Memo/AbstractMemo.java | |
1216 | =================================================================== | |
1217 | --- head-src/Base/Memo/AbstractMemo.java (nonexistent) | |
1218 | +++ head-src/Base/Memo/AbstractMemo.java (working copy) | |
1219 | +package Base.Memo; | |
1220 | + | |
1221 | +import java.util.concurrent.atomic.AtomicBoolean; | |
1222 | + | |
1223 | + | |
1224 | + | |
1225 | + | |
1226 | +/** | |
1227 | + * A {@link StatsSet} which overrides methods to prevent doing useless database operations if there is no changes since last edit (it uses an AtomicBoolean to keep edition tracking).<br> | |
1228 | + * <br> | |
1229 | + * It also has 2 abstract methods, named restoreMe() and storeMe(). | |
1230 | + */ | |
1231 | +public abstract class AbstractMemo extends StatsSet | |
1232 | +{ | |
1233 | + /** | |
1234 | + * | |
1235 | + */ | |
1236 | + private static final long serialVersionUID = 1L; | |
1237 | + private final AtomicBoolean _hasChanges = new AtomicBoolean(false); | |
1238 | + | |
1239 | + @Override | |
1240 | + public final void set(String name, boolean value) | |
1241 | + { | |
1242 | + _hasChanges.compareAndSet(false, true); | |
1243 | + super.set(name, value); | |
1244 | + } | |
1245 | + | |
1246 | + @Override | |
1247 | + public final void set(String name, double value) | |
1248 | + { | |
1249 | + _hasChanges.compareAndSet(false, true); | |
1250 | + super.set(name, value); | |
1251 | + } | |
1252 | + | |
1253 | + @Override | |
1254 | + public final void set(String name, Enum<?> value) | |
1255 | + { | |
1256 | + _hasChanges.compareAndSet(false, true); | |
1257 | + super.set(name, value); | |
1258 | + } | |
1259 | + | |
1260 | + @Override | |
1261 | + public final void set(String name, int value) | |
1262 | + { | |
1263 | + _hasChanges.compareAndSet(false, true); | |
1264 | + super.set(name, value); | |
1265 | + } | |
1266 | + | |
1267 | + @Override | |
1268 | + public final void set(String name, long value) | |
1269 | + { | |
1270 | + _hasChanges.compareAndSet(false, true); | |
1271 | + super.set(name, value); | |
1272 | + } | |
1273 | + | |
1274 | + @Override | |
1275 | + public final void set(String name, String value) | |
1276 | + { | |
1277 | + _hasChanges.compareAndSet(false, true); | |
1278 | + super.set(name, value); | |
1279 | + } | |
1280 | + | |
1281 | + /** | |
1282 | + * @return {@code true} if changes are made since last load/save. | |
1283 | + */ | |
1284 | + public final boolean hasChanges() | |
1285 | + { | |
1286 | + return _hasChanges.get(); | |
1287 | + } | |
1288 | + | |
1289 | + /** | |
1290 | + * Atomically sets the value to the given updated value if the current value {@code ==} the expected value. | |
1291 | + * @param expect | |
1292 | + * @param update | |
1293 | + * @return {@code true} if successful. {@code false} return indicates that the actual value was not equal to the expected value. | |
1294 | + */ | |
1295 | + public final boolean compareAndSetChanges(boolean expect, boolean update) | |
1296 | + { | |
1297 | + return _hasChanges.compareAndSet(expect, update); | |
1298 | + } | |
1299 | + | |
1300 | + /** | |
1301 | + * Removes variable | |
1302 | + * @param name | |
1303 | + */ | |
1304 | + public final void remove(String name) | |
1305 | + { | |
1306 | + _hasChanges.compareAndSet(false, true); | |
1307 | + unset(name); | |
1308 | + } | |
1309 | + | |
1310 | + protected abstract boolean restoreMe(); | |
1311 | + | |
1312 | + protected abstract boolean storeMe(); | |
1313 | +} | |
1314 | ||
1315 | ### Eclipse Workspace Patch 1.0 | |
1316 | #P L2jFrozen_GameServer | |
1317 | Index: head-src/Base/Memo/StatsSet.java | |
1318 | =================================================================== | |
1319 | --- head-src/Base/Memo/StatsSet.java (nonexistent) | |
1320 | +++ head-src/Base/Memo/StatsSet.java (working copy) | |
1321 | +package Base.Memo; | |
1322 | + | |
1323 | +import java.util.ArrayList; | |
1324 | +import java.util.Collections; | |
1325 | +import java.util.HashMap; | |
1326 | +import java.util.List; | |
1327 | +import java.util.Map; | |
1328 | + | |
1329 | +/** | |
1330 | + * This class is used in order to have a set of couples (key,value).<BR> | |
1331 | + * Methods deployed are accessors to the set (add/get value from its key) and addition of a whole set in the current one. | |
1332 | + * @author mkizub, G1ta0 | |
1333 | + */ | |
1334 | +public class StatsSet extends HashMap<String, Object> | |
1335 | +{ | |
1336 | + /** | |
1337 | + * | |
1338 | + */ | |
1339 | + private static final long serialVersionUID = 1L; | |
1340 | + | |
1341 | + public StatsSet() | |
1342 | + { | |
1343 | + super(); | |
1344 | + } | |
1345 | + | |
1346 | + public StatsSet(final int size) | |
1347 | + { | |
1348 | + super(size); | |
1349 | + } | |
1350 | + | |
1351 | + public StatsSet(final StatsSet set) | |
1352 | + { | |
1353 | + super(set); | |
1354 | + } | |
1355 | + | |
1356 | + public void set(final String key, final Object value) | |
1357 | + { | |
1358 | + put(key, value); | |
1359 | + } | |
1360 | + | |
1361 | + public void set(final String key, final String value) | |
1362 | + { | |
1363 | + put(key, value); | |
1364 | + } | |
1365 | + | |
1366 | + public void set(final String key, final boolean value) | |
1367 | + { | |
1368 | + put(key, value ? Boolean.TRUE : Boolean.FALSE); | |
1369 | + } | |
1370 | + | |
1371 | + public void set(final String key, final int value) | |
1372 | + { | |
1373 | + put(key, value); | |
1374 | + } | |
1375 | + | |
1376 | + public void set(final String key, final int[] value) | |
1377 | + { | |
1378 | + put(key, value); | |
1379 | + } | |
1380 | + | |
1381 | + public void set(final String key, final long value) | |
1382 | + { | |
1383 | + put(key, value); | |
1384 | + } | |
1385 | + | |
1386 | + public void set(final String key, final double value) | |
1387 | + { | |
1388 | + put(key, value); | |
1389 | + } | |
1390 | + | |
1391 | + public void set(final String key, final Enum<?> value) | |
1392 | + { | |
1393 | + put(key, value); | |
1394 | + } | |
1395 | + | |
1396 | + public void unset(final String key) | |
1397 | + { | |
1398 | + remove(key); | |
1399 | + } | |
1400 | + | |
1401 | + public boolean getBool(final String key) | |
1402 | + { | |
1403 | + final Object val = get(key); | |
1404 | + | |
1405 | + if (val instanceof Boolean) | |
1406 | + return (Boolean) val; | |
1407 | + if (val instanceof String) | |
1408 | + return Boolean.parseBoolean((String) val); | |
1409 | + if (val instanceof Number) | |
1410 | + return ((Number) val).intValue() != 0; | |
1411 | + | |
1412 | + throw new IllegalArgumentException("StatsSet : Boolean value required, but found: " + val + " for key: " + key + "."); | |
1413 | + } | |
1414 | + | |
1415 | + public boolean getBool(final String key, final boolean defaultValue) | |
1416 | + { | |
1417 | + final Object val = get(key); | |
1418 | + | |
1419 | + if (val instanceof Boolean) | |
1420 | + return (Boolean) val; | |
1421 | + if (val instanceof String) | |
1422 | + return Boolean.parseBoolean((String) val); | |
1423 | + if (val instanceof Number) | |
1424 | + return ((Number) val).intValue() != 0; | |
1425 | + | |
1426 | + return defaultValue; | |
1427 | + } | |
1428 | + | |
1429 | + public byte getByte(final String key) | |
1430 | + { | |
1431 | + final Object val = get(key); | |
1432 | + | |
1433 | + if (val instanceof Number) | |
1434 | + return ((Number) val).byteValue(); | |
1435 | + if (val instanceof String) | |
1436 | + return Byte.parseByte((String) val); | |
1437 | + | |
1438 | + throw new IllegalArgumentException("StatsSet : Byte value required, but found: " + val + " for key: " + key + "."); | |
1439 | + } | |
1440 | + | |
1441 | + public byte getByte(final String key, final byte defaultValue) | |
1442 | + { | |
1443 | + final Object val = get(key); | |
1444 | + | |
1445 | + if (val instanceof Number) | |
1446 | + return ((Number) val).byteValue(); | |
1447 | + if (val instanceof String) | |
1448 | + return Byte.parseByte((String) val); | |
1449 | + | |
1450 | + return defaultValue; | |
1451 | + } | |
1452 | + | |
1453 | + public double getDouble(final String key) | |
1454 | + { | |
1455 | + final Object val = get(key); | |
1456 | + | |
1457 | + if (val instanceof Number) | |
1458 | + return ((Number) val).doubleValue(); | |
1459 | + if (val instanceof String) | |
1460 | + return Double.parseDouble((String) val); | |
1461 | + if (val instanceof Boolean) | |
1462 | + return (Boolean) val ? 1. : 0.; | |
1463 | + | |
1464 | + throw new IllegalArgumentException("StatsSet : Double value required, but found: " + val + " for key: " + key + "."); | |
1465 | + } | |
1466 | + | |
1467 | + public double getDouble(final String key, final double defaultValue) | |
1468 | + { | |
1469 | + final Object val = get(key); | |
1470 | + | |
1471 | + if (val instanceof Number) | |
1472 | + return ((Number) val).doubleValue(); | |
1473 | + if (val instanceof String) | |
1474 | + return Double.parseDouble((String) val); | |
1475 | + if (val instanceof Boolean) | |
1476 | + return (Boolean) val ? 1. : 0.; | |
1477 | + | |
1478 | + return defaultValue; | |
1479 | + } | |
1480 | + | |
1481 | + public double[] getDoubleArray(final String key) | |
1482 | + { | |
1483 | + final Object val = get(key); | |
1484 | + | |
1485 | + if (val instanceof double[]) | |
1486 | + return (double[]) val; | |
1487 | + if (val instanceof Number) | |
1488 | + return new double[] | |
1489 | + { | |
1490 | + ((Number) val).doubleValue() | |
1491 | + }; | |
1492 | + if (val instanceof String) | |
1493 | + { | |
1494 | + final String[] vals = ((String) val).split(";"); | |
1495 | + | |
1496 | + final double[] result = new double[vals.length]; | |
1497 | + | |
1498 | + int i = 0; | |
1499 | + for (final String v : vals) | |
1500 | + result[i++] = Double.parseDouble(v); | |
1501 | + | |
1502 | + return result; | |
1503 | + } | |
1504 | + | |
1505 | + throw new IllegalArgumentException("StatsSet : Double array required, but found: " + val + " for key: " + key + "."); | |
1506 | + } | |
1507 | + | |
1508 | + public float getFloat(final String key) | |
1509 | + { | |
1510 | + final Object val = get(key); | |
1511 | + | |
1512 | + if (val instanceof Number) | |
1513 | + return ((Number) val).floatValue(); | |
1514 | + if (val instanceof String) | |
1515 | + return Float.parseFloat((String) val); | |
1516 | + if (val instanceof Boolean) | |
1517 | + return (Boolean) val ? 1 : 0; | |
1518 | + | |
1519 | + throw new IllegalArgumentException("StatsSet : Float value required, but found: " + val + " for key: " + key + "."); | |
1520 | + } | |
1521 | + | |
1522 | + public float getFloat(final String key, final float defaultValue) | |
1523 | + { | |
1524 | + final Object val = get(key); | |
1525 | + | |
1526 | + if (val instanceof Number) | |
1527 | + return ((Number) val).floatValue(); | |
1528 | + if (val instanceof String) | |
1529 | + return Float.parseFloat((String) val); | |
1530 | + if (val instanceof Boolean) | |
1531 | + return (Boolean) val ? 1 : 0; | |
1532 | + | |
1533 | + return defaultValue; | |
1534 | + } | |
1535 | + | |
1536 | + public int getInteger(final String key) | |
1537 | + { | |
1538 | + final Object val = get(key); | |
1539 | + | |
1540 | + if (val instanceof Number) | |
1541 | + return ((Number) val).intValue(); | |
1542 | + if (val instanceof String) | |
1543 | + return Integer.parseInt((String) val); | |
1544 | + if (val instanceof Boolean) | |
1545 | + return (Boolean) val ? 1 : 0; | |
1546 | + | |
1547 | + throw new IllegalArgumentException("StatsSet : Integer value required, but found: " + val + " for key: " + key + "."); | |
1548 | + } | |
1549 | + | |
1550 | + public int getInteger(final String key, final int defaultValue) | |
1551 | + { | |
1552 | + final Object val = get(key); | |
1553 | + | |
1554 | + if (val instanceof Number) | |
1555 | + return ((Number) val).intValue(); | |
1556 | + if (val instanceof String) | |
1557 | + return Integer.parseInt((String) val); | |
1558 | + if (val instanceof Boolean) | |
1559 | + return (Boolean) val ? 1 : 0; | |
1560 | + | |
1561 | + return defaultValue; | |
1562 | + } | |
1563 | + | |
1564 | + public int[] getIntegerArray(final String key) | |
1565 | + { | |
1566 | + final Object val = get(key); | |
1567 | + | |
1568 | + if (val instanceof int[]) | |
1569 | + return (int[]) val; | |
1570 | + if (val instanceof Number) | |
1571 | + return new int[] | |
1572 | + { | |
1573 | + ((Number) val).intValue() | |
1574 | + }; | |
1575 | + if (val instanceof String) | |
1576 | + { | |
1577 | + final String[] vals = ((String) val).split(";"); | |
1578 | + | |
1579 | + final int[] result = new int[vals.length]; | |
1580 | + | |
1581 | + int i = 0; | |
1582 | + for (final String v : vals) | |
1583 | + result[i++] = Integer.parseInt(v); | |
1584 | + | |
1585 | + return result; | |
1586 | + } | |
1587 | + | |
1588 | + throw new IllegalArgumentException("StatsSet : Integer array required, but found: " + val + " for key: " + key + "."); | |
1589 | + } | |
1590 | + | |
1591 | + public int[] getIntegerArray(final String key, final int[] defaultArray) | |
1592 | + { | |
1593 | + try | |
1594 | + { | |
1595 | + return getIntegerArray(key); | |
1596 | + } | |
1597 | + catch (IllegalArgumentException e) | |
1598 | + { | |
1599 | + return defaultArray; | |
1600 | + } | |
1601 | + } | |
1602 | + | |
1603 | + @SuppressWarnings("unchecked") | |
1604 | + public <T> List<T> getList(final String key) | |
1605 | + { | |
1606 | + final Object val = get(key); | |
1607 | + | |
1608 | + if (val == null) | |
1609 | + return Collections.emptyList(); | |
1610 | + | |
1611 | + return (ArrayList<T>) val; | |
1612 | + } | |
1613 | + | |
1614 | + public long getLong(final String key) | |
1615 | + { | |
1616 | + final Object val = get(key); | |
1617 | + | |
1618 | + if (val instanceof Number) | |
1619 | + return ((Number) val).longValue(); | |
1620 | + if (val instanceof String) | |
1621 | + return Long.parseLong((String) val); | |
1622 | + if (val instanceof Boolean) | |
1623 | + return (Boolean) val ? 1L : 0L; | |
1624 | + | |
1625 | + throw new IllegalArgumentException("StatsSet : Long value required, but found: " + val + " for key: " + key + "."); | |
1626 | + } | |
1627 | + | |
1628 | + public long getLong(final String key, final long defaultValue) | |
1629 | + { | |
1630 | + final Object val = get(key); | |
1631 | + | |
1632 | + if (val instanceof Number) | |
1633 | + return ((Number) val).longValue(); | |
1634 | + if (val instanceof String) | |
1635 | + return Long.parseLong((String) val); | |
1636 | + if (val instanceof Boolean) | |
1637 | + return (Boolean) val ? 1L : 0L; | |
1638 | + | |
1639 | + return defaultValue; | |
1640 | + } | |
1641 | + | |
1642 | + public long[] getLongArray(final String key) | |
1643 | + { | |
1644 | + final Object val = get(key); | |
1645 | + | |
1646 | + if (val instanceof long[]) | |
1647 | + return (long[]) val; | |
1648 | + if (val instanceof Number) | |
1649 | + return new long[] | |
1650 | + { | |
1651 | + ((Number) val).longValue() | |
1652 | + }; | |
1653 | + if (val instanceof String) | |
1654 | + { | |
1655 | + final String[] vals = ((String) val).split(";"); | |
1656 | + | |
1657 | + final long[] result = new long[vals.length]; | |
1658 | + | |
1659 | + int i = 0; | |
1660 | + for (final String v : vals) | |
1661 | + result[i++] = Integer.parseInt(v); | |
1662 | + | |
1663 | + return result; | |
1664 | + } | |
1665 | + | |
1666 | + throw new IllegalArgumentException("StatsSet : Long array required, but found: " + val + " for key: " + key + "."); | |
1667 | + } | |
1668 | + | |
1669 | + @SuppressWarnings("unchecked") | |
1670 | + public <T, U> Map<T, U> getMap(final String key) | |
1671 | + { | |
1672 | + final Object val = get(key); | |
1673 | + | |
1674 | + if (val == null) | |
1675 | + return Collections.emptyMap(); | |
1676 | + | |
1677 | + return (HashMap<T, U>) val; | |
1678 | + } | |
1679 | + | |
1680 | + public String getString(final String key) | |
1681 | + { | |
1682 | + final Object val = get(key); | |
1683 | + | |
1684 | + if (val != null) | |
1685 | + return String.valueOf(val); | |
1686 | + | |
1687 | + throw new IllegalArgumentException("StatsSet : String value required, but unspecified for key: " + key + "."); | |
1688 | + } | |
1689 | + | |
1690 | + public String getString(final String key, final String defaultValue) | |
1691 | + { | |
1692 | + final Object val = get(key); | |
1693 | + | |
1694 | + if (val != null) | |
1695 | + return String.valueOf(val); | |
1696 | + | |
1697 | + return defaultValue; | |
1698 | + } | |
1699 | + | |
1700 | + public String[] getStringArray(final String key) | |
1701 | + { | |
1702 | + final Object val = get(key); | |
1703 | + | |
1704 | + if (val instanceof String[]) | |
1705 | + return (String[]) val; | |
1706 | + if (val instanceof String) | |
1707 | + return ((String) val).split(";"); | |
1708 | + | |
1709 | + throw new IllegalArgumentException("StatsSet : String array required, but found: " + val + " for key: " + key + "."); | |
1710 | + } | |
1711 | + | |
1712 | + @SuppressWarnings("unchecked") | |
1713 | + public <A> A getObject(final String key, final Class<A> type) | |
1714 | + { | |
1715 | + final Object val = get(key); | |
1716 | + | |
1717 | + if (val == null || !type.isAssignableFrom(val.getClass())) | |
1718 | + return null; | |
1719 | + | |
1720 | + return (A) val; | |
1721 | + } | |
1722 | + | |
1723 | + @SuppressWarnings("unchecked") | |
1724 | + public <E extends Enum<E>> E getEnum(final String name, final Class<E> enumClass) | |
1725 | + { | |
1726 | + final Object val = get(name); | |
1727 | + | |
1728 | + if (val != null && enumClass.isInstance(val)) | |
1729 | + return (E) val; | |
1730 | + if (val instanceof String) | |
1731 | + return Enum.valueOf(enumClass, (String) val); | |
1732 | + | |
1733 | + throw new IllegalArgumentException("Enum value of type " + enumClass.getName() + "required, but found: " + val + "."); | |
1734 | + } | |
1735 | + | |
1736 | + @SuppressWarnings("unchecked") | |
1737 | + public <E extends Enum<E>> E getEnum(final String name, final Class<E> enumClass, final E defaultValue) | |
1738 | + { | |
1739 | + final Object val = get(name); | |
1740 | + | |
1741 | + if (val != null && enumClass.isInstance(val)) | |
1742 | + return (E) val; | |
1743 | + if (val instanceof String) | |
1744 | + return Enum.valueOf(enumClass, (String) val); | |
1745 | + | |
1746 | + return defaultValue; | |
1747 | + } | |
1748 | +} | |
1749 | ||
1750 | ### Eclipse Workspace Patch 1.0 | |
1751 | #P L2jFrozen_GameServer | |
1752 | Index: head-src/Base/Memo/PlayerMemo.java | |
1753 | =================================================================== | |
1754 | --- head-src/Base/Memo/PlayerMemo.java (nonexistent) | |
1755 | +++ head-src/Base/Memo/PlayerMemo.java (working copy) | |
1756 | +package Base.Memo; | |
1757 | + | |
1758 | +import java.sql.Connection; | |
1759 | +import java.sql.PreparedStatement; | |
1760 | +import java.sql.ResultSet; | |
1761 | +import java.sql.SQLException; | |
1762 | +import java.util.logging.Level; | |
1763 | +import java.util.logging.Logger; | |
1764 | + | |
1765 | +import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance; | |
1766 | + | |
1767 | +import com.l2jfrozen.util.database.L2DatabaseFactory; | |
1768 | + | |
1769 | +import Base.Util.Mysql; | |
1770 | + | |
1771 | + | |
1772 | + | |
1773 | +/** | |
1774 | + * An implementation of {@link AbstractMemo} used for Player. There is a restore/save system. | |
1775 | + */ | |
1776 | +public class PlayerMemo extends AbstractMemo | |
1777 | +{ | |
1778 | + /** | |
1779 | + * | |
1780 | + */ | |
1781 | + private static final long serialVersionUID = 1L; | |
1782 | + | |
1783 | + private static final Logger LOG = Logger.getLogger(PlayerMemo.class.getName()); | |
1784 | + | |
1785 | + private static final String SELECT_QUERY = "SELECT * FROM character_memo WHERE charId = ?"; | |
1786 | + private static final String DELETE_QUERY = "DELETE FROM character_memo WHERE charId = ?"; | |
1787 | + private static final String INSERT_QUERY = "INSERT INTO character_memo (charId, var, val) VALUES (?, ?, ?)"; | |
1788 | + | |
1789 | + private final int _objectId; | |
1790 | + | |
1791 | + | |
1792 | + | |
1793 | + | |
1794 | + /** | |
1795 | + * @param objectId | |
1796 | + */ | |
1797 | + public PlayerMemo(int objectId) | |
1798 | + { | |
1799 | + _objectId = objectId; | |
1800 | + restoreMe(); | |
1801 | + } | |
1802 | + | |
1803 | + | |
1804 | + // When var exist | |
1805 | + public static void changeValue(L2PcInstance player, String name, String value) | |
1806 | + { | |
1807 | + if (!player.getMemos().containsKey(name)) | |
1808 | + { | |
1809 | + player.sendMessage("Variable is not exist..."); | |
1810 | + return; | |
1811 | + } | |
1812 | + | |
1813 | + getVarObject(player, name).setValue(value); | |
1814 | + Mysql.set("UPDATE character_memo_dungeon SET value=? WHERE obj_id=? AND name=?", value, player.getObjectId(), name); | |
1815 | + } | |
1816 | + | |
1817 | + public static void setVar(L2PcInstance player, String name, String value, long expirationTime) | |
1818 | + { | |
1819 | + if (player.getMemos().containsKey(name)) | |
1820 | + getVarObject(player, name).stopExpireTask(); | |
1821 | + | |
1822 | + player.getMemos().put(name, new PlayerVar(player, name, value, expirationTime)); | |
1823 | + Mysql.set("REPLACE INTO character_memo_dungeon (obj_id, name, value, expire_time) VALUES (?,?,?,?)", player.getObjectId(), name, value, expirationTime); | |
1824 | + } | |
1825 | + | |
1826 | + public static void setVar(L2PcInstance player, String name, int value, long expirationTime) | |
1827 | + { | |
1828 | + setVar(player, name, String.valueOf(value), expirationTime); | |
1829 | + } | |
1830 | + | |
1831 | + public void setVar(L2PcInstance player, String name, long value, long expirationTime) | |
1832 | + { | |
1833 | + setVar(player, name, String.valueOf(value), expirationTime); | |
1834 | + } | |
1835 | + | |
1836 | + | |
1837 | + public static PlayerVar getVarObject(L2PcInstance player, String name) | |
1838 | + { | |
1839 | + if(player.getMemos() == null) | |
1840 | + return null; | |
1841 | + | |
1842 | + return (PlayerVar) player.getMemos().get(name); | |
1843 | + } | |
1844 | + | |
1845 | + public static long getVarTimeToExpire(L2PcInstance player, String name) | |
1846 | + { | |
1847 | + try | |
1848 | + { | |
1849 | + return getVarObject(player, name).getTimeToExpire(); | |
1850 | + } | |
1851 | + catch (NullPointerException npe) | |
1852 | + { | |
1853 | + } | |
1854 | + | |
1855 | + return 0; | |
1856 | + } | |
1857 | + | |
1858 | + public static void unsetVar(L2PcInstance player, String name) | |
1859 | + { | |
1860 | + if (name == null) | |
1861 | + return; | |
1862 | + | |
1863 | + // Avoid possible unsetVar that have elements for login | |
1864 | + if(player == null) | |
1865 | + return; | |
1866 | + | |
1867 | + PlayerVar pv = (PlayerVar) player.getMemos().get(name); | |
1868 | + | |
1869 | + if (pv != null) | |
1870 | + { | |
1871 | + if(name.contains("delete_temp_item")) | |
1872 | + pv.getOwner().deleteTempItem(Integer.parseInt(pv.getValue())); | |
1873 | + else if(name.contains("solo_hero")) { | |
1874 | + pv.getOwner().broadcastCharInfo(); | |
1875 | + pv.getOwner().broadcastUserInfo(); | |
1876 | + } | |
1877 | + | |
1878 | + | |
1879 | + Mysql.set("DELETE FROM character_memo_dungeon WHERE obj_id=? AND name=? LIMIT 1", pv.getOwner().getObjectId(), name); | |
1880 | + | |
1881 | + pv.stopExpireTask(); | |
1882 | + } | |
1883 | + } | |
1884 | + | |
1885 | + public static void deleteExpiredVar(L2PcInstance player, String name, String value) | |
1886 | + { | |
1887 | + if (name == null) | |
1888 | + return; | |
1889 | + | |
1890 | + if(name.contains("delete_temp_item")) | |
1891 | + player.deleteTempItem(Integer.parseInt(value)); | |
1892 | + /*else if(name.contains("solo_hero")) // Useless | |
1893 | + player.broadcastCharInfo();*/ | |
1894 | + | |
1895 | + Mysql.set("DELETE FROM character_memo_dungeon WHERE obj_id=? AND name=? LIMIT 1", player.getObjectId(), name); | |
1896 | + } | |
1897 | + | |
1898 | + public static String getVar(L2PcInstance player, String name) | |
1899 | + { | |
1900 | + PlayerVar pv = getVarObject(player, name); | |
1901 | + | |
1902 | + if (pv == null) | |
1903 | + return null; | |
1904 | + | |
1905 | + return pv.getValue(); | |
1906 | + } | |
1907 | + | |
1908 | + public static long getVarTimeToExpireSQL(L2PcInstance player, String name) | |
1909 | + { | |
1910 | + long expireTime = 0; | |
1911 | + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) | |
1912 | + { | |
1913 | + PreparedStatement statement = con.prepareStatement("SELECT expire_time FROM character_memo_dungeon WHERE obj_id = ? AND name = ?"); | |
1914 | + statement.setLong(1, player.getObjectId()); | |
1915 | + statement.setString(2, name); | |
1916 | + for (ResultSet rset = statement.executeQuery(); rset.next();) | |
1917 | + expireTime = rset.getLong("expire_time"); | |
1918 | + | |
1919 | + con.close(); | |
1920 | + statement.close(); | |
1921 | + } | |
1922 | + catch (Exception e) | |
1923 | + { | |
1924 | + e.printStackTrace(); | |
1925 | + } | |
1926 | + | |
1927 | + return expireTime; | |
1928 | + } | |
1929 | + | |
1930 | + public static boolean getVarB(L2PcInstance player, String name, boolean defaultVal) | |
1931 | + { | |
1932 | + PlayerVar pv = getVarObject(player, name); | |
1933 | + | |
1934 | + if (pv == null) | |
1935 | + return defaultVal; | |
1936 | + | |
1937 | + return pv.getValueBoolean(); | |
1938 | + } | |
1939 | + | |
1940 | + public static boolean getVarB(L2PcInstance player, String name) | |
1941 | + { | |
1942 | + return getVarB(player, name, false); | |
1943 | + } | |
1944 | + | |
1945 | + public long getVarLong(L2PcInstance player, String name) | |
1946 | + { | |
1947 | + return getVarLong(player, name, 0L); | |
1948 | + } | |
1949 | + | |
1950 | + public long getVarLong(L2PcInstance player, String name, long defaultVal) | |
1951 | + { | |
1952 | + long result = defaultVal; | |
1953 | + String var = getVar(player, name); | |
1954 | + if (var != null) | |
1955 | + result = Long.parseLong(var); | |
1956 | + | |
1957 | + return result; | |
1958 | + } | |
1959 | + | |
1960 | + public static int getVarInt(L2PcInstance player, String name) | |
1961 | + { | |
1962 | + return getVarInt(player, name, 0); | |
1963 | + } | |
1964 | + | |
1965 | + public static int getVarInt(L2PcInstance player, String name, int defaultVal) | |
1966 | + { | |
1967 | + int result = defaultVal; | |
1968 | + String var = getVar(player, name); | |
1969 | + if (var != null) | |
1970 | + { | |
1971 | + if(var.equalsIgnoreCase("true")) | |
1972 | + result = 1; | |
1973 | + else if(var.equalsIgnoreCase("false")) | |
1974 | + result = 0; | |
1975 | + else | |
1976 | + result = Integer.parseInt(var); | |
1977 | + } | |
1978 | + return result; | |
1979 | + } | |
1980 | + | |
1981 | + public static void loadVariables(L2PcInstance player) | |
1982 | + { | |
1983 | + Connection con = null; | |
1984 | + PreparedStatement offline = null; | |
1985 | + ResultSet rs = null; | |
1986 | + try | |
1987 | + { | |
1988 | + con = L2DatabaseFactory.getInstance().getConnection(); | |
1989 | + offline = con.prepareStatement("SELECT * FROM character_memo_dungeon WHERE obj_id = ?"); | |
1990 | + offline.setInt(1, player.getObjectId()); | |
1991 | + rs = offline.executeQuery(); | |
1992 | + | |
1993 | + while (rs.next()) | |
1994 | + { | |
1995 | + String name = rs.getString("name"); | |
1996 | + String value = rs.getString("value"); | |
1997 | + long expire_time = rs.getLong("expire_time"); | |
1998 | + long curtime = System.currentTimeMillis(); | |
1999 | + | |
2000 | + if ((expire_time <= curtime) && (expire_time > 0)) | |
2001 | + { | |
2002 | + deleteExpiredVar(player, name, rs.getString("value")); //TODO: Remove the Var | |
2003 | + continue; | |
2004 | + } | |
2005 | + | |
2006 | + player.getMemos().put(name, new PlayerVar(player, name, value, expire_time)); | |
2007 | + } | |
2008 | + | |
2009 | + con.close(); | |
2010 | + } | |
2011 | + catch (Exception e) | |
2012 | + { | |
2013 | + e.printStackTrace(); | |
2014 | + } | |
2015 | + finally | |
2016 | + { | |
2017 | + Mysql.closeQuietly(con, offline, rs); | |
2018 | + } | |
2019 | + } | |
2020 | + | |
2021 | + public static String getVarValue(L2PcInstance player, String var, String defaultString) | |
2022 | + { | |
2023 | + String value = null; | |
2024 | + Connection con = null; | |
2025 | + PreparedStatement offline = null; | |
2026 | + ResultSet rs = null; | |
2027 | + try | |
2028 | + { | |
2029 | + con = L2DatabaseFactory.getInstance().getConnection(); | |
2030 | + offline = con.prepareStatement("SELECT value FROM character_memo_dungeon WHERE obj_id = ? AND name = ?"); | |
2031 | + offline.setInt(1, player.getObjectId()); | |
2032 | + offline.setString(2, var); | |
2033 | + rs = offline.executeQuery(); | |
2034 | + if (rs.next()) | |
2035 | + value = rs.getString("value"); | |
2036 | + | |
2037 | + con.close(); | |
2038 | + } | |
2039 | + catch (Exception e) | |
2040 | + { | |
2041 | + e.printStackTrace(); | |
2042 | + } | |
2043 | + finally | |
2044 | + { | |
2045 | + Mysql.closeQuietly(con, offline, rs); | |
2046 | + } | |
2047 | + return value == null ? defaultString : value; | |
2048 | + } | |
2049 | + | |
2050 | + public static String getVarValue(int objectId, String var, String defaultString) | |
2051 | + { | |
2052 | + String value = null; | |
2053 | + Connection con = null; | |
2054 | + PreparedStatement offline = null; | |
2055 | + ResultSet rs = null; | |
2056 | + try | |
2057 | + { | |
2058 | + con = L2DatabaseFactory.getInstance().getConnection(); | |
2059 | + offline = con.prepareStatement("SELECT value FROM character_memo_dungeon WHERE obj_id = ? AND name = ?"); | |
2060 | + offline.setInt(1, objectId); | |
2061 | + offline.setString(2, var); | |
2062 | + rs = offline.executeQuery(); | |
2063 | + if (rs.next()) | |
2064 | + value = rs.getString("value"); | |
2065 | + | |
2066 | + con.close(); | |
2067 | + } | |
2068 | + catch (Exception e) | |
2069 | + { | |
2070 | + e.printStackTrace(); | |
2071 | + } | |
2072 | + finally | |
2073 | + { | |
2074 | + Mysql.closeQuietly(con, offline, rs); | |
2075 | + } | |
2076 | + return value == null ? defaultString : value; | |
2077 | + } | |
2078 | + | |
2079 | + @Override | |
2080 | + public boolean restoreMe() | |
2081 | + { | |
2082 | + // Restore previous variables. | |
2083 | + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) | |
2084 | + { | |
2085 | + PreparedStatement st = con.prepareStatement(SELECT_QUERY); | |
2086 | + st.setInt(1, _objectId); | |
2087 | + | |
2088 | + ResultSet rset = st.executeQuery(); | |
2089 | + while (rset.next()) | |
2090 | + set(rset.getString("var"), rset.getString("val")); | |
2091 | + | |
2092 | + rset.close(); | |
2093 | + st.close(); | |
2094 | + } | |
2095 | + catch (SQLException e) | |
2096 | + { | |
2097 | + LOG.log(Level.SEVERE, "Couldn't restore variables for player id: " + _objectId, e); | |
2098 | + return false; | |
2099 | + } | |
2100 | + finally | |
2101 | + { | |
2102 | + compareAndSetChanges(true, false); | |
2103 | + } | |
2104 | + return true; | |
2105 | + } | |
2106 | + | |
2107 | + @Override | |
2108 | + public boolean storeMe() | |
2109 | + { | |
2110 | + // No changes, nothing to store. | |
2111 | + if (!hasChanges()) | |
2112 | + return false; | |
2113 | + | |
2114 | + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) | |
2115 | + { | |
2116 | + // Clear previous entries. | |
2117 | + PreparedStatement st = con.prepareStatement(DELETE_QUERY); | |
2118 | + st.setInt(1, _objectId); | |
2119 | + st.execute(); | |
2120 | + st.close(); | |
2121 | + | |
2122 | + // Insert all variables. | |
2123 | + st = con.prepareStatement(INSERT_QUERY); | |
2124 | + st.setInt(1, _objectId); | |
2125 | + for (Entry<String, Object> entry : entrySet()) | |
2126 | + { | |
2127 | + st.setString(2, entry.getKey()); | |
2128 | + st.setString(3, String.valueOf(entry.getValue())); | |
2129 | + st.addBatch(); | |
2130 | + } | |
2131 | + st.executeBatch(); | |
2132 | + st.close(); | |
2133 | + } | |
2134 | + catch (SQLException e) | |
2135 | + { | |
2136 | + LOG.log(Level.SEVERE, "Couldn't update variables for player id: " + _objectId, e); | |
2137 | + return false; | |
2138 | + } | |
2139 | + finally | |
2140 | + { | |
2141 | + compareAndSetChanges(true, false); | |
2142 | + } | |
2143 | + return true; | |
2144 | + } | |
2145 | +} | |
2146 | ||
2147 | ||
2148 | ### Eclipse Workspace Patch 1.0 | |
2149 | #P L2jFrozen_GameServer | |
2150 | Index: head-src/Base/Memo/PlayerVar.java | |
2151 | =================================================================== | |
2152 | --- head-src/Base/Memo/PlayerVar.java (nonexistent) | |
2153 | +++ head-src/Base/Memo/PlayerVar.java (working copy) | |
2154 | +package Base.Memo; | |
2155 | + | |
2156 | +import java.util.concurrent.ScheduledFuture; | |
2157 | + | |
2158 | +import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance; | |
2159 | +import com.l2jfrozen.gameserver.thread.ThreadPool; | |
2160 | + | |
2161 | + | |
2162 | + | |
2163 | + | |
2164 | +public class PlayerVar | |
2165 | +{ | |
2166 | + private L2PcInstance owner; | |
2167 | + private String name; | |
2168 | + private String value; | |
2169 | + private long expire_time; | |
2170 | + | |
2171 | + @SuppressWarnings("rawtypes") | |
2172 | + private ScheduledFuture task; | |
2173 | + | |
2174 | + public PlayerVar(L2PcInstance owner, String name, String value, long expire_time) | |
2175 | + { | |
2176 | + this.owner = owner; | |
2177 | + this.name = name; | |
2178 | + this.value = value; | |
2179 | + this.expire_time = expire_time; | |
2180 | + | |
2181 | + if (expire_time > 0) // if expires schedule expiration | |
2182 | + { | |
2183 | + task = ThreadPool.schedule(new PlayerVarExpireTask(this), expire_time - System.currentTimeMillis()); | |
2184 | + } | |
2185 | + } | |
2186 | + | |
2187 | + public String getName() | |
2188 | + { | |
2189 | + return name; | |
2190 | + } | |
2191 | + | |
2192 | + public L2PcInstance getOwner() | |
2193 | + { | |
2194 | + return owner; | |
2195 | + } | |
2196 | + | |
2197 | + public boolean hasExpired() | |
2198 | + { | |
2199 | + return task == null || task.isDone(); | |
2200 | + } | |
2201 | + | |
2202 | + public long getTimeToExpire() | |
2203 | + { | |
2204 | + return expire_time - System.currentTimeMillis(); | |
2205 | + } | |
2206 | + | |
2207 | + public String getValue() | |
2208 | + { | |
2209 | + return value; | |
2210 | + } | |
2211 | + | |
2212 | + public boolean getValueBoolean() | |
2213 | + { | |
2214 | + if (isNumeric(value)) | |
2215 | + return Integer.parseInt(value) > 0; | |
2216 | + | |
2217 | + return value.equalsIgnoreCase("true"); | |
2218 | + } | |
2219 | + | |
2220 | + public void setValue(String val) | |
2221 | + { | |
2222 | + value = val; | |
2223 | + } | |
2224 | + | |
2225 | + public void stopExpireTask() | |
2226 | + { | |
2227 | + if (task != null && !task.isDone()) | |
2228 | + { | |
2229 | + task.cancel(true); | |
2230 | + } | |
2231 | + } | |
2232 | + | |
2233 | + private static class PlayerVarExpireTask implements Runnable | |
2234 | + { | |
2235 | + private PlayerVar _pv; | |
2236 | + | |
2237 | + public PlayerVarExpireTask(PlayerVar pv) | |
2238 | + { | |
2239 | + _pv = pv; | |
2240 | + } | |
2241 | + | |
2242 | + @Override | |
2243 | + public void run() | |
2244 | + { | |
2245 | + L2PcInstance pc = _pv.getOwner(); | |
2246 | + if (pc == null) | |
2247 | + { | |
2248 | + return; | |
2249 | + } | |
2250 | + | |
2251 | + PlayerMemo.unsetVar(pc, _pv.getName()); | |
2252 | + } | |
2253 | + } | |
2254 | + | |
2255 | + public boolean isNumeric(String str) | |
2256 | + { | |
2257 | + try | |
2258 | + { | |
2259 | + @SuppressWarnings("unused") | |
2260 | + double d = Double.parseDouble(str); | |
2261 | + } | |
2262 | + catch (NumberFormatException nfe) | |
2263 | + { | |
2264 | + return false; | |
2265 | + } | |
2266 | + return true; | |
2267 | + } | |
2268 | +} | |
2269 | ||
2270 | ||
2271 | ### Eclipse Workspace Patch 1.0 | |
2272 | #P L2jFrozen_GameServer | |
2273 | Index: head-src/Base/Util/Mysql.java | |
2274 | =================================================================== | |
2275 | --- head-src/Base/Util/Mysql.java (nonexistent) | |
2276 | +++ head-src/Base/Util/Mysql.java (working copy) | |
2277 | +package Base.Util; | |
2278 | + | |
2279 | +import java.sql.Connection; | |
2280 | +import java.sql.PreparedStatement; | |
2281 | +import java.sql.ResultSet; | |
2282 | +import java.sql.SQLException; | |
2283 | +import java.sql.Statement; | |
2284 | +import java.util.logging.Logger; | |
2285 | + | |
2286 | +import com.l2jfrozen.util.database.L2DatabaseFactory; | |
2287 | + | |
2288 | + | |
2289 | + | |
2290 | + | |
2291 | + | |
2292 | +public abstract class Mysql | |
2293 | +{ | |
2294 | + public static final Logger _log = Logger.getLogger(Mysql.class.getName()); | |
2295 | + | |
2296 | + /** | |
2297 | + * Performs a simple sql queries where unnecessary control parameters <BR> | |
2298 | + * NOTE: In this method, the parameters passed are not valid for SQL-injection! | |
2299 | + * @param db | |
2300 | + * @param query | |
2301 | + * @param vars | |
2302 | + * @return | |
2303 | + */ | |
2304 | + public static boolean setEx(L2DatabaseFactory db, String query, Object... vars) | |
2305 | + { | |
2306 | + Connection con = null; | |
2307 | + Statement statement = null; | |
2308 | + PreparedStatement pstatement = null; | |
2309 | + boolean successed = true; | |
2310 | + | |
2311 | + try | |
2312 | + { | |
2313 | + if(db == null) | |
2314 | + db = L2DatabaseFactory.getInstance(); | |
2315 | + | |
2316 | + con = db.getConnection(); | |
2317 | + if(vars.length == 0) | |
2318 | + { | |
2319 | + statement = con.createStatement(); | |
2320 | + statement.executeUpdate(query); | |
2321 | + statement.close(); | |
2322 | + } | |
2323 | + else | |
2324 | + { | |
2325 | + pstatement = con.prepareStatement(query); | |
2326 | + setVars(pstatement, vars); | |
2327 | + pstatement.executeUpdate(); | |
2328 | + pstatement.close(); | |
2329 | + } | |
2330 | + con.close(); | |
2331 | + } | |
2332 | + catch(Exception e) | |
2333 | + { | |
2334 | + _log.warning("Could not execute update '" + query + "': " + e); | |
2335 | + e.printStackTrace(); | |
2336 | + successed = false; | |
2337 | + } | |
2338 | + finally | |
2339 | + { | |
2340 | + closeQuietly(con, pstatement); | |
2341 | + closeQuietly(statement); | |
2342 | + } | |
2343 | + return successed; | |
2344 | + } | |
2345 | + | |
2346 | + public static void setVars(PreparedStatement statement, Object... vars) throws SQLException | |
2347 | + { | |
2348 | + Number n; | |
2349 | + long long_val; | |
2350 | + double double_val; | |
2351 | + for(int i = 0; i < vars.length; i++) | |
2352 | + if(vars[i] instanceof Number) | |
2353 | + { | |
2354 | + n = (Number) vars[i]; | |
2355 | + long_val = n.longValue(); | |
2356 | + double_val = n.doubleValue(); | |
2357 | + if(long_val == double_val) | |
2358 | + statement.setLong(i + 1, long_val); | |
2359 | + else | |
2360 | + statement.setDouble(i + 1, double_val); | |
2361 | + } | |
2362 | + else if(vars[i] instanceof String) | |
2363 | + statement.setString(i + 1, (String) vars[i]); | |
2364 | + } | |
2365 | + | |
2366 | + public static boolean set(String query, Object... vars) | |
2367 | + { | |
2368 | + return setEx(null, query, vars); | |
2369 | + } | |
2370 | + | |
2371 | + public static boolean set(String query) | |
2372 | + { | |
2373 | + return setEx(null, query); | |
2374 | + } | |
2375 | + | |
2376 | + public static void closeQuietly(Connection conn) | |
2377 | + { | |
2378 | + try { | |
2379 | + close(conn); | |
2380 | + } catch (SQLException e) { // NOPMD | |
2381 | + // quiet | |
2382 | + } | |
2383 | + } | |
2384 | + | |
2385 | + public static void closeQuietly(Connection conn, Statement stmt, ResultSet rs) { | |
2386 | + | |
2387 | + try { | |
2388 | + closeQuietly(rs); | |
2389 | + } finally { | |
2390 | + try { | |
2391 | + closeQuietly(stmt); | |
2392 | + } finally { | |
2393 | + closeQuietly(conn); | |
2394 | + } | |
2395 | + } | |
2396 | + } | |
2397 | + | |
2398 | + public static void closeQuietly(Connection conn, Statement stmt) | |
2399 | + { | |
2400 | + try { | |
2401 | + closeQuietly(stmt); | |
2402 | + } finally { | |
2403 | + closeQuietly(conn); | |
2404 | + } | |
2405 | + } | |
2406 | + | |
2407 | + public static void closeQuietly(ResultSet rs) { | |
2408 | + try { | |
2409 | + close(rs); | |
2410 | + } catch (SQLException e) { // NOPMD | |
2411 | + // quiet | |
2412 | + } | |
2413 | + } | |
2414 | + | |
2415 | + public static void closeQuietly(Statement stmt) { | |
2416 | + try { | |
2417 | + close(stmt); | |
2418 | + } catch (SQLException e) { // NOPMD | |
2419 | + // quiet | |
2420 | + } | |
2421 | + } | |
2422 | + | |
2423 | + public static void close(Connection conn) throws SQLException { | |
2424 | + if (conn != null) { | |
2425 | + conn.close(); | |
2426 | + } | |
2427 | + } | |
2428 | + | |
2429 | + public static void close(ResultSet rs) throws SQLException { | |
2430 | + if (rs != null) { | |
2431 | + rs.close(); | |
2432 | + } | |
2433 | + } | |
2434 | + | |
2435 | + public static void close(Statement stmt) throws SQLException { | |
2436 | + if (stmt != null) { | |
2437 | + stmt.close(); | |
2438 | + } | |
2439 | + } | |
2440 | + | |
2441 | +} | |
2442 | ||
2443 | ||
2444 | ### Eclipse Workspace Patch 1.0 | |
2445 | #P L2jFrozen_GameServer | |
2446 | Index: head-src/Base/XML/XMLDocumentFactory.java | |
2447 | =================================================================== | |
2448 | --- head-src/Base/XML/XMLDocumentFactory.java (nonexistent) | |
2449 | +++ head-src/Base/XML/XMLDocumentFactory.java (working copy) | |
2450 | +package Base.XML; | |
2451 | + | |
2452 | +import java.io.File; | |
2453 | + | |
2454 | +import javax.xml.parsers.DocumentBuilder; | |
2455 | +import javax.xml.parsers.DocumentBuilderFactory; | |
2456 | + | |
2457 | +import org.w3c.dom.Document; | |
2458 | + | |
2459 | +/** | |
2460 | + * @author Forsaiken | |
2461 | + */ | |
2462 | +public final class XMLDocumentFactory | |
2463 | +{ | |
2464 | + public static final XMLDocumentFactory getInstance() | |
2465 | + { | |
2466 | + return SingletonHolder._instance; | |
2467 | + } | |
2468 | + | |
2469 | + private final DocumentBuilder _builder; | |
2470 | + | |
2471 | + protected XMLDocumentFactory() throws Exception | |
2472 | + { | |
2473 | + try | |
2474 | + { | |
2475 | + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
2476 | + factory.setValidating(false); | |
2477 | + factory.setIgnoringComments(true); | |
2478 | + | |
2479 | + _builder = factory.newDocumentBuilder(); | |
2480 | + } | |
2481 | + catch (Exception e) | |
2482 | + { | |
2483 | + throw new Exception("Failed initializing", e); | |
2484 | + } | |
2485 | + } | |
2486 | + | |
2487 | + public final Document loadDocument(final String filePath) throws Exception | |
2488 | + { | |
2489 | + return loadDocument(new File(filePath)); | |
2490 | + } | |
2491 | + | |
2492 | + public final Document loadDocument(final File file) throws Exception | |
2493 | + { | |
2494 | + if (!file.exists() || !file.isFile()) | |
2495 | + throw new Exception("File: " + file.getAbsolutePath() + " doesn't exist and/or is not a file."); | |
2496 | + | |
2497 | + return _builder.parse(file); | |
2498 | + } | |
2499 | + | |
2500 | + public final Document newDocument() | |
2501 | + { | |
2502 | + return _builder.newDocument(); | |
2503 | + } | |
2504 | + | |
2505 | + private static class SingletonHolder | |
2506 | + { | |
2507 | + protected static final XMLDocumentFactory _instance; | |
2508 | + | |
2509 | + static | |
2510 | + { | |
2511 | + try | |
2512 | + { | |
2513 | + _instance = new XMLDocumentFactory(); | |
2514 | + } | |
2515 | + catch (Exception e) | |
2516 | + { | |
2517 | + throw new ExceptionInInitializerError(e); | |
2518 | + } | |
2519 | + } | |
2520 | + } | |
2521 | +} | |
2522 | ||
2523 | ### Eclipse Workspace Patch 1.0 | |
2524 | #P L2jFrozen_GameServer | |
2525 | Index: head-src/Base/Config/ExProperties.java | |
2526 | =================================================================== | |
2527 | --- head-src/Base/Config/ExProperties.java (nonexistent) | |
2528 | +++ head-src/Base/Config/ExProperties.java (working copy) | |
2529 | +/* | |
2530 | + * This program is free software: you can redistribute it and/or modify it under | |
2531 | + * the terms of the GNU General Public License as published by the Free Software | |
2532 | + * Foundation, either version 3 of the License, or (at your option) any later | |
2533 | + * version. | |
2534 | + * | |
2535 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
2536 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
2537 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
2538 | + * details. | |
2539 | + * | |
2540 | + * You should have received a copy of the GNU General Public License along with | |
2541 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
2542 | + */ | |
2543 | +package Base.Config; | |
2544 | + | |
2545 | +import java.io.File; | |
2546 | +import java.io.FileInputStream; | |
2547 | +import java.io.IOException; | |
2548 | +import java.io.InputStream; | |
2549 | +import java.util.Properties; | |
2550 | + | |
2551 | +/** | |
2552 | + * @author G1ta0 | |
2553 | + */ | |
2554 | +public class ExProperties extends Properties | |
2555 | +{ | |
2556 | + private static final long serialVersionUID = 1L; | |
2557 | + | |
2558 | + public static final String defaultDelimiter = "[\\s,;]+"; | |
2559 | + | |
2560 | + public void load(final String fileName) throws IOException | |
2561 | + { | |
2562 | + load(new File(fileName)); | |
2563 | + } | |
2564 | + | |
2565 | + public void load(final File file) throws IOException | |
2566 | + { | |
2567 | + try (InputStream is = new FileInputStream(file)) | |
2568 | + { | |
2569 | + load(is); | |
2570 | + } | |
2571 | + } | |
2572 | + | |
2573 | + public boolean getProperty(final String name, final boolean defaultValue) | |
2574 | + { | |
2575 | + boolean val = defaultValue; | |
2576 | + | |
2577 | + final String value; | |
2578 | + | |
2579 | + if ((value = super.getProperty(name, null)) != null) | |
2580 | + val = Boolean.parseBoolean(value); | |
2581 | + | |
2582 | + return val; | |
2583 | + } | |
2584 | + | |
2585 | + public int getProperty(final String name, final int defaultValue) | |
2586 | + { | |
2587 | + int val = defaultValue; | |
2588 | + | |
2589 | + final String value; | |
2590 | + | |
2591 | + if ((value = super.getProperty(name, null)) != null) | |
2592 | + val = Integer.parseInt(value); | |
2593 | + | |
2594 | + return val; | |
2595 | + } | |
2596 | + | |
2597 | + public long getProperty(final String name, final long defaultValue) | |
2598 | + { | |
2599 | + long val = defaultValue; | |
2600 | + | |
2601 | + final String value; | |
2602 | + | |
2603 | + if ((value = super.getProperty(name, null)) != null) | |
2604 | + val = Long.parseLong(value); | |
2605 | + | |
2606 | + return val; | |
2607 | + } | |
2608 | + | |
2609 | + public double getProperty(final String name, final double defaultValue) | |
2610 | + { | |
2611 | + double val = defaultValue; | |
2612 | + | |
2613 | + final String value; | |
2614 | + | |
2615 | + if ((value = super.getProperty(name, null)) != null) | |
2616 | + val = Double.parseDouble(value); | |
2617 | + | |
2618 | + return val; | |
2619 | + } | |
2620 | + | |
2621 | + public String[] getProperty(final String name, final String[] defaultValue) | |
2622 | + { | |
2623 | + return getProperty(name, defaultValue, defaultDelimiter); | |
2624 | + } | |
2625 | + | |
2626 | + public String[] getProperty(final String name, final String[] defaultValue, final String delimiter) | |
2627 | + { | |
2628 | + String[] val = defaultValue; | |
2629 | + final String value; | |
2630 | + | |
2631 | + if ((value = super.getProperty(name, null)) != null) | |
2632 | + val = value.split(delimiter); | |
2633 | + | |
2634 | + return val; | |
2635 | + } | |
2636 | + | |
2637 | + public boolean[] getProperty(final String name, final boolean[] defaultValue) | |
2638 | + { | |
2639 | + return getProperty(name, defaultValue, defaultDelimiter); | |
2640 | + } | |
2641 | + | |
2642 | + public boolean[] getProperty(final String name, final boolean[] defaultValue, final String delimiter) | |
2643 | + { | |
2644 | + boolean[] val = defaultValue; | |
2645 | + final String value; | |
2646 | + | |
2647 | + if ((value = super.getProperty(name, null)) != null) | |
2648 | + { | |
2649 | + final String[] values = value.split(delimiter); | |
2650 | + val = new boolean[values.length]; | |
2651 | + for (int i = 0; i < val.length; i++) | |
2652 | + val[i] = Boolean.parseBoolean(values[i]); | |
2653 | + } | |
2654 | + | |
2655 | + return val; | |
2656 | + } | |
2657 | + | |
2658 | + public int[] getProperty(final String name, final int[] defaultValue) | |
2659 | + { | |
2660 | + return getProperty(name, defaultValue, defaultDelimiter); | |
2661 | + } | |
2662 | + | |
2663 | + public int[] getProperty(final String name, final int[] defaultValue, final String delimiter) | |
2664 | + { | |
2665 | + int[] val = defaultValue; | |
2666 | + final String value; | |
2667 | + | |
2668 | + if ((value = super.getProperty(name, null)) != null) | |
2669 | + { | |
2670 | + final String[] values = value.split(delimiter); | |
2671 | + val = new int[values.length]; | |
2672 | + for (int i = 0; i < val.length; i++) | |
2673 | + val[i] = Integer.parseInt(values[i]); | |
2674 | + } | |
2675 | + | |
2676 | + return val; | |
2677 | + } | |
2678 | + | |
2679 | + public long[] getProperty(final String name, final long[] defaultValue) | |
2680 | + { | |
2681 | + return getProperty(name, defaultValue, defaultDelimiter); | |
2682 | + } | |
2683 | + | |
2684 | + public long[] getProperty(final String name, final long[] defaultValue, final String delimiter) | |
2685 | + { | |
2686 | + long[] val = defaultValue; | |
2687 | + final String value; | |
2688 | + | |
2689 | + if ((value = super.getProperty(name, null)) != null) | |
2690 | + { | |
2691 | + final String[] values = value.split(delimiter); | |
2692 | + val = new long[values.length]; | |
2693 | + for (int i = 0; i < val.length; i++) | |
2694 | + val[i] = Long.parseLong(values[i]); | |
2695 | + } | |
2696 | + | |
2697 | + return val; | |
2698 | + } | |
2699 | + | |
2700 | + public double[] getProperty(final String name, final double[] defaultValue) | |
2701 | + { | |
2702 | + return getProperty(name, defaultValue, defaultDelimiter); | |
2703 | + } | |
2704 | + | |
2705 | + public double[] getProperty(final String name, final double[] defaultValue, final String delimiter) | |
2706 | + { | |
2707 | + double[] val = defaultValue; | |
2708 | + final String value; | |
2709 | + | |
2710 | + if ((value = super.getProperty(name, null)) != null) | |
2711 | + { | |
2712 | + final String[] values = value.split(delimiter); | |
2713 | + val = new double[values.length]; | |
2714 | + for (int i = 0; i < val.length; i++) | |
2715 | + val[i] = Double.parseDouble(values[i]); | |
2716 | + } | |
2717 | + | |
2718 | + return val; | |
2719 | + } | |
2720 | +} | |
2721 | ||
2722 | ### Eclipse Workspace Patch 1.0 | |
2723 | #P L2jFrozen_GameServer | |
2724 | Index: head-src/com/l2jfrozen/gameserver/thread/ThreadPool.java | |
2725 | =================================================================== | |
2726 | --- head-src/com/l2jfrozen/gameserver/thread/ThreadPool.java (nonexistent) | |
2727 | +++ head-src/com/l2jfrozen/gameserver/thread/ThreadPool.java (working copy) | |
2728 | +package com.l2jfrozen.gameserver.thread; | |
2729 | + | |
2730 | +import java.util.concurrent.ArrayBlockingQueue; | |
2731 | +import java.util.concurrent.ScheduledFuture; | |
2732 | +import java.util.concurrent.ScheduledThreadPoolExecutor; | |
2733 | +import java.util.concurrent.ThreadPoolExecutor; | |
2734 | +import java.util.concurrent.TimeUnit; | |
2735 | +import java.util.logging.Logger; | |
2736 | + | |
2737 | +import com.l2jfrozen.Config; | |
2738 | + | |
2739 | +/** | |
2740 | + * This class handles thread pooling system. It relies on two ThreadPoolExecutor arrays, which poolers number is generated using config. | |
2741 | +* <p> | |
2742 | +* Those arrays hold following pools : | |
2743 | +* </p> | |
2744 | +* <ul> | |
2745 | +* <li>Scheduled pool keeps a track about incoming, future events.</li> | |
2746 | +* <li>Instant pool handles short-life events.</li> | |
2747 | +* </ul> | |
2748 | +*/ | |
2749 | +public final class ThreadPool | |
2750 | +{ | |
2751 | + protected static final Logger LOG = Logger.getLogger(ThreadPool.class.getName()); | |
2752 | + | |
2753 | + private static final long MAX_DELAY = TimeUnit.NANOSECONDS.toMillis(Long.MAX_VALUE - System.nanoTime()) / 2; | |
2754 | + | |
2755 | + private static int _threadPoolRandomizer; | |
2756 | + | |
2757 | + protected static ScheduledThreadPoolExecutor[] _scheduledPools; | |
2758 | + protected static ThreadPoolExecutor[] _instantPools; | |
2759 | + | |
2760 | + /** | |
2761 | + * Init the different pools, based on Config. It is launched only once, on Gameserver instance. | |
2762 | + */ | |
2763 | + public static void init() | |
2764 | + { | |
2765 | + // Feed scheduled pool. | |
2766 | + int poolCount = Config.SCHEDULED_THREAD_POOL_COUNT; | |
2767 | + if (poolCount == -1) | |
2768 | + poolCount = Runtime.getRuntime().availableProcessors(); | |
2769 | + | |
2770 | + _scheduledPools = new ScheduledThreadPoolExecutor[poolCount]; | |
2771 | + for (int i = 0; i < poolCount; i++) | |
2772 | + _scheduledPools[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL); | |
2773 | + | |
2774 | + // Feed instant pool. | |
2775 | + poolCount = Config.INSTANT_THREAD_POOL_COUNT; | |
2776 | + if (poolCount == -1) | |
2777 | + poolCount = Runtime.getRuntime().availableProcessors(); | |
2778 | + | |
2779 | + _instantPools = new ThreadPoolExecutor[poolCount]; | |
2780 | + for (int i = 0; i < poolCount; i++) | |
2781 | + _instantPools[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000)); | |
2782 | + | |
2783 | + // Prestart core threads. | |
2784 | + for (ScheduledThreadPoolExecutor threadPool : _scheduledPools) | |
2785 | + threadPool.prestartAllCoreThreads(); | |
2786 | + | |
2787 | + for (ThreadPoolExecutor threadPool : _instantPools) | |
2788 | + threadPool.prestartAllCoreThreads(); | |
2789 | + | |
2790 | + // Launch purge task. | |
2791 | + scheduleAtFixedRate(new Runnable() | |
2792 | + { | |
2793 | + @Override | |
2794 | + public void run() | |
2795 | + { | |
2796 | + for (ScheduledThreadPoolExecutor threadPool : _scheduledPools) | |
2797 | + threadPool.purge(); | |
2798 | + | |
2799 | + for (ThreadPoolExecutor threadPool : _instantPools) | |
2800 | + threadPool.purge(); | |
2801 | + } | |
2802 | + }, 600000, 600000); | |
2803 | + | |
2804 | + LOG.info("ThreadPool: Initialized " + getPoolSize(_scheduledPools) + "/" + getMaximumPoolSize(_scheduledPools) + " scheduled, " + getPoolSize(_instantPools) + "/" + getMaximumPoolSize(_instantPools) + " instant thread(s)."); | |
2805 | + } | |
2806 | + | |
2807 | + /** | |
2808 | + * Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity. | |
2809 | + * @param r : the task to execute. | |
2810 | + * @param delay : the time from now to delay execution. | |
2811 | + * @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion. | |
2812 | + */ | |
2813 | + public static ScheduledFuture<?> schedule(Runnable r, long delay) | |
2814 | + { | |
2815 | + try | |
2816 | + { | |
2817 | + return getPool(_scheduledPools).schedule(new TaskWrapper(r), validate(delay), TimeUnit.MILLISECONDS); | |
2818 | + } | |
2819 | + catch (Exception e) | |
2820 | + { | |
2821 | + return null; | |
2822 | + } | |
2823 | + } | |
2824 | + | |
2825 | + /** | |
2826 | + * Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity. | |
2827 | + * @param r : the task to execute. | |
2828 | + * @param delay : the time from now to delay execution. | |
2829 | + * @param period : the period between successive executions. | |
2830 | + * @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation. | |
2831 | + */ | |
2832 | + public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period) | |
2833 | + { | |
2834 | + try | |
2835 | + { | |
2836 | + return getPool(_scheduledPools).scheduleAtFixedRate(new TaskWrapper(r), validate(delay), validate(period), TimeUnit.MILLISECONDS); | |
2837 | + } | |
2838 | + catch (Exception e) | |
2839 | + { | |
2840 | + return null; | |
2841 | + } | |
2842 | + } | |
2843 | + | |
2844 | + /** | |
2845 | + * Executes the given task sometime in the future. | |
2846 | + * @param r : the task to execute. | |
2847 | + */ | |
2848 | + public static void execute(Runnable r) | |
2849 | + { | |
2850 | + try | |
2851 | + { | |
2852 | + getPool(_instantPools).execute(new TaskWrapper(r)); | |
2853 | + } | |
2854 | + catch (Exception e) | |
2855 | + { | |
2856 | + } | |
2857 | + } | |
2858 | + | |
2859 | + /** | |
2860 | + * Retrieve stats of current running thread pools. | |
2861 | + */ | |
2862 | + public static void getStats() | |
2863 | + { | |
2864 | + for (int i = 0; i < _scheduledPools.length; i++) | |
2865 | + { | |
2866 | + final ScheduledThreadPoolExecutor threadPool = _scheduledPools[i]; | |
2867 | + | |
2868 | + LOG.info("================================================="); | |
2869 | + LOG.info("Scheduled pool #" + i + ":"); | |
2870 | + LOG.info("\tgetActiveCount: ...... " + threadPool.getActiveCount()); | |
2871 | + LOG.info("\tgetCorePoolSize: ..... " + threadPool.getCorePoolSize()); | |
2872 | + LOG.info("\tgetPoolSize: ......... " + threadPool.getPoolSize()); | |
2873 | + LOG.info("\tgetLargestPoolSize: .. " + threadPool.getLargestPoolSize()); | |
2874 | + LOG.info("\tgetMaximumPoolSize: .. " + threadPool.getMaximumPoolSize()); | |
2875 | + LOG.info("\tgetCompletedTaskCount: " + threadPool.getCompletedTaskCount()); | |
2876 | + LOG.info("\tgetQueuedTaskCount: .. " + threadPool.getQueue().size()); | |
2877 | + LOG.info("\tgetTaskCount: ........ " + threadPool.getTaskCount()); | |
2878 | + } | |
2879 | + | |
2880 | + for (int i = 0; i < _instantPools.length; i++) | |
2881 | + { | |
2882 | + final ThreadPoolExecutor threadPool = _instantPools[i]; | |
2883 | + | |
2884 | + LOG.info("================================================="); | |
2885 | + LOG.info("Instant pool #" + i + ":"); | |
2886 | + LOG.info("\tgetActiveCount: ...... " + threadPool.getActiveCount()); | |
2887 | + LOG.info("\tgetCorePoolSize: ..... " + threadPool.getCorePoolSize()); | |
2888 | + LOG.info("\tgetPoolSize: ......... " + threadPool.getPoolSize()); | |
2889 | + LOG.info("\tgetLargestPoolSize: .. " + threadPool.getLargestPoolSize()); | |
2890 | + LOG.info("\tgetMaximumPoolSize: .. " + threadPool.getMaximumPoolSize()); | |
2891 | + LOG.info("\tgetCompletedTaskCount: " + threadPool.getCompletedTaskCount()); | |
2892 | + LOG.info("\tgetQueuedTaskCount: .. " + threadPool.getQueue().size()); | |
2893 | + LOG.info("\tgetTaskCount: ........ " + threadPool.getTaskCount()); | |
2894 | + } | |
2895 | + } | |
2896 | + | |
2897 | + /** | |
2898 | + * Shutdown thread pooling system correctly. Send different informations. | |
2899 | + */ | |
2900 | + public static void shutdown() | |
2901 | + { | |
2902 | + try | |
2903 | + { | |
2904 | + System.out.println("ThreadPool: Shutting down."); | |
2905 | + | |
2906 | + for (ScheduledThreadPoolExecutor threadPool : _scheduledPools) | |
2907 | + threadPool.shutdownNow(); | |
2908 | + | |
2909 | + for (ThreadPoolExecutor threadPool : _instantPools) | |
2910 | + threadPool.shutdownNow(); | |
2911 | + } | |
2912 | + catch (Throwable t) | |
2913 | + { | |
2914 | + t.printStackTrace(); | |
2915 | + } | |
2916 | + } | |
2917 | + | |
2918 | + /** | |
2919 | + * @param <T> : The pool type. | |
2920 | + * @param threadPools : The pool array to check. | |
2921 | + * @return the less fed pool. | |
2922 | + */ | |
2923 | + private static <T> T getPool(T[] threadPools) | |
2924 | + { | |
2925 | + return threadPools[_threadPoolRandomizer++ % threadPools.length]; | |
2926 | + } | |
2927 | + | |
2928 | + /** | |
2929 | + * @param delay : The delay to validate. | |
2930 | + * @return a secured value, from 0 to MAX_DELAY. | |
2931 | + */ | |
2932 | + private static long validate(long delay) | |
2933 | + { | |
2934 | + return Math.max(0, Math.min(MAX_DELAY, delay)); | |
2935 | + } | |
2936 | + | |
2937 | + /** | |
2938 | + * @param threadPools : The pool array to check. | |
2939 | + * @return the overall actual pools size. | |
2940 | + */ | |
2941 | + private static long getPoolSize(ThreadPoolExecutor[] threadPools) | |
2942 | + { | |
2943 | + long result = 0; | |
2944 | + | |
2945 | + for (ThreadPoolExecutor threadPool : threadPools) | |
2946 | + result += threadPool.getPoolSize(); | |
2947 | + | |
2948 | + return result; | |
2949 | + } | |
2950 | + | |
2951 | + /** | |
2952 | + * @param threadPools : The pool array to check. | |
2953 | + * @return the overall maximum pools size. | |
2954 | + */ | |
2955 | + private static long getMaximumPoolSize(ThreadPoolExecutor[] threadPools) | |
2956 | + { | |
2957 | + long result = 0; | |
2958 | + | |
2959 | + for (ThreadPoolExecutor threadPool : threadPools) | |
2960 | + result += threadPool.getMaximumPoolSize(); | |
2961 | + | |
2962 | + return result; | |
2963 | + } | |
2964 | + | |
2965 | + public static final class TaskWrapper implements Runnable | |
2966 | + { | |
2967 | + private final Runnable _runnable; | |
2968 | + | |
2969 | + public TaskWrapper(Runnable runnable) | |
2970 | + { | |
2971 | + _runnable = runnable; | |
2972 | + } | |
2973 | + | |
2974 | + @Override | |
2975 | + public void run() | |
2976 | + { | |
2977 | + try | |
2978 | + { | |
2979 | + _runnable.run(); | |
2980 | + } | |
2981 | + catch (RuntimeException e) | |
2982 | + { | |
2983 | + LOG.warning("Exception in a Runnable execution:" + e); | |
2984 | + } | |
2985 | + } | |
2986 | + } | |
2987 | +} | |
2988 | ||
2989 | ||
2990 | ### Eclipse Workspace Patch 1.0 | |
2991 | #P L2jFrozen_GameServer | |
2992 | Index: head-src/com/l2jfrozen/gameserver/network/serverpackets/NpcHtmlMessage.java | |
2993 | =================================================================== | |
2994 | --- head-src/com/l2jfrozen/gameserver/network/serverpackets/NpcHtmlMessage.java (nonexistent) | |
2995 | +++ head-src/com/l2jfrozen/gameserver/network/serverpackets/NpcHtmlMessage.java (working copy) | |
2996 | ||
2997 | ||
2998 | /** | |
2999 | * Gets the content. | |
3000 | * @return the content | |
3001 | */ | |
3002 | public String getContent() | |
3003 | { | |
3004 | return _html; | |
3005 | } | |
3006 | ||
3007 | + /** | |
3008 | + * @return | |
3009 | + */ | |
3010 | + public String getHtml() | |
3011 | + { | |
3012 | + return _html; | |
3013 | + } | |
3014 | ||
3015 | ||
3016 | ### Eclipse Workspace Patch 1.0 | |
3017 | #P L2jFrozen_GameServer | |
3018 | Index: head-src/com/l2jfrozen/gameserver/network/serverpackets/SocialAction.java | |
3019 | =================================================================== | |
3020 | --- head-src/com/l2jfrozen/gameserver/network/serverpackets/SocialAction.java (nonexistent) | |
3021 | +++ head-src/com/l2jfrozen/gameserver/network/serverpackets/SocialAction.java (working copy) | |
3022 | ||
3023 | package com.l2jfrozen.gameserver.network.serverpackets; | |
3024 | ||
3025 | +import com.l2jfrozen.gameserver.model.actor.instance.L2DungeonManagerInstance; | |
3026 | ||
3027 | ||
3028 | ||
3029 | ||
3030 | /** | |
3031 | * 0x3d SocialAction dd | |
3032 | * @param playerId | |
3033 | * @param actionId | |
3034 | */ | |
3035 | public SocialAction(final int playerId, final int actionId) | |
3036 | { | |
3037 | _charObjId = playerId; | |
3038 | _actionId = actionId; | |
3039 | } | |
3040 | ||
3041 | + /** | |
3042 | + * 0x3d SocialAction dd | |
3043 | + * @param l2DungeonManagerInstance | |
3044 | + * @param actionId | |
3045 | + */ | |
3046 | + public SocialAction(final L2DungeonManagerInstance l2DungeonManagerInstance, final int actionId) | |
3047 | + { | |
3048 | + this._charObjId = 0; | |
3049 | + _actionId = actionId; | |
3050 | + } | |
3051 | ||
3052 | ||
3053 | ||
3054 | ||
3055 | ### Eclipse Workspace Patch 1.0 | |
3056 | #P L2jFrozen_GameServer | |
3057 | Index: head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonMobInstance.java | |
3058 | =================================================================== | |
3059 | --- head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonMobInstance.java (nonexistent) | |
3060 | +++ head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonMobInstance.java (working copy) | |
3061 | +/* | |
3062 | + * This program is free software: you can redistribute it and/or modify it under | |
3063 | + * the terms of the GNU General Public License as published by the Free Software | |
3064 | + * Foundation, either version 3 of the License, or (at your option) any later | |
3065 | + * version. | |
3066 | + * | |
3067 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
3068 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
3069 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
3070 | + * details. | |
3071 | + * | |
3072 | + * You should have received a copy of the GNU General Public License along with | |
3073 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
3074 | + */ | |
3075 | +package com.l2jfrozen.gameserver.model.actor.instance; | |
3076 | + | |
3077 | +import com.l2jfrozen.gameserver.model.L2Character; | |
3078 | +import com.l2jfrozen.gameserver.templates.L2NpcTemplate; | |
3079 | +import com.l2jfrozen.gameserver.thread.ThreadPool; | |
3080 | + | |
3081 | +import Base.Dev.Dungeon.Dungeon; | |
3082 | + | |
3083 | + | |
3084 | + | |
3085 | +/** | |
3086 | + * @author Juvenil Walker | |
3087 | + * | |
3088 | + */ | |
3089 | + | |
3090 | + | |
3091 | +public class L2DungeonMobInstance extends L2MonsterInstance | |
3092 | +{ | |
3093 | + private Dungeon dungeon; | |
3094 | + | |
3095 | + public L2DungeonMobInstance(int objectId, L2NpcTemplate template) | |
3096 | + { | |
3097 | + super(objectId, template); | |
3098 | + } | |
3099 | + | |
3100 | + @Override | |
3101 | + public boolean doDie(L2Character killer) | |
3102 | + { | |
3103 | + if (!super.doDie(killer)) | |
3104 | + return false; | |
3105 | + | |
3106 | + if(dungeon != null) // It will be dungeon == null when mob is spawned from admin and not from dungeon | |
3107 | + ThreadPool.schedule(() -> dungeon.onMobKill(this), 1000*2); | |
3108 | + | |
3109 | + return true; | |
3110 | + } | |
3111 | + | |
3112 | + public void setDungeon(Dungeon dungeon) | |
3113 | + { | |
3114 | + this.dungeon = dungeon; | |
3115 | + } | |
3116 | +} | |
3117 | ||
3118 | ### Eclipse Workspace Patch 1.0 | |
3119 | #P L2jFrozen_GameServer | |
3120 | Index: head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonManagerInstance.java | |
3121 | =================================================================== | |
3122 | --- head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonManagerInstance.java (nonexistent) | |
3123 | +++ head-src/com/l2jfrozen/gameserver/model/actor/instance/L2DungeonManagerInstance.java (working copy) | |
3124 | +package com.l2jfrozen.gameserver.model.actor.instance; | |
3125 | + | |
3126 | +import java.util.StringTokenizer; | |
3127 | + | |
3128 | + | |
3129 | + | |
3130 | + | |
3131 | +import com.l2jfrozen.Config; | |
3132 | +import com.l2jfrozen.gameserver.ai.CtrlIntention; | |
3133 | +import com.l2jfrozen.gameserver.datatables.sql.ItemTable; | |
3134 | +import com.l2jfrozen.gameserver.network.serverpackets.ActionFailed; | |
3135 | +import com.l2jfrozen.gameserver.network.serverpackets.ExShowScreenMessage; | |
3136 | +import com.l2jfrozen.gameserver.network.serverpackets.MyTargetSelected; | |
3137 | +import com.l2jfrozen.gameserver.network.serverpackets.NpcHtmlMessage; | |
3138 | +import com.l2jfrozen.gameserver.network.serverpackets.SocialAction; | |
3139 | +import com.l2jfrozen.gameserver.network.serverpackets.ValidateLocation; | |
3140 | +import com.l2jfrozen.gameserver.templates.L2NpcTemplate; | |
3141 | +import com.l2jfrozen.util.random.Rnd; | |
3142 | + | |
3143 | +import Base.Dev.Dungeon.DungeonManager; | |
3144 | + | |
3145 | + | |
3146 | + | |
3147 | +public class L2DungeonManagerInstance extends L2NpcInstance | |
3148 | +{ | |
3149 | + public L2DungeonManagerInstance(int objectId, L2NpcTemplate template) | |
3150 | + { | |
3151 | + super(objectId, template); | |
3152 | + } | |
3153 | + | |
3154 | + @Override | |
3155 | + public void onAction(L2PcInstance player) | |
3156 | + { | |
3157 | + if (this != player.getTarget()) | |
3158 | + { | |
3159 | + player.setTarget(this); | |
3160 | + player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel() - getLevel())); | |
3161 | + player.sendPacket(new ValidateLocation(this)); | |
3162 | + } | |
3163 | + else if (isInsideRadius(player, INTERACTION_DISTANCE, false, false)) | |
3164 | + { | |
3165 | + SocialAction sa = new SocialAction(this, Rnd.get(8)); | |
3166 | + broadcastPacket(sa); | |
3167 | + showChatWindow(player); | |
3168 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
3169 | + } | |
3170 | + else | |
3171 | + { | |
3172 | + player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this); | |
3173 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
3174 | + } | |
3175 | + } | |
3176 | + | |
3177 | + | |
3178 | + | |
3179 | + public static String getPlayerStatus(L2PcInstance player, int dungeonId) | |
3180 | + { | |
3181 | + String s = "You can enter"; | |
3182 | + | |
3183 | + String ip = player.getIP(); // Is ip or hwid? | |
3184 | + if (DungeonManager.getInstance().getPlayerData().containsKey(ip) && DungeonManager.getInstance().getPlayerData().get(ip)[dungeonId] > 0) | |
3185 | + { | |
3186 | + long total = (DungeonManager.getInstance().getPlayerData().get(ip)[dungeonId] + (1000*60*60*12)) - System.currentTimeMillis(); | |
3187 | + | |
3188 | + if (total > 0) | |
3189 | + { | |
3190 | + int hours = (int) (total/1000/60/60); | |
3191 | + int minutes = (int) ((total/1000/60) - hours*60); | |
3192 | + int seconds = (int) ((total/1000) - (hours*60*60 + minutes*60)); | |
3193 | + | |
3194 | + s = String.format("%02d:%02d:%02d", hours, minutes, seconds); | |
3195 | + } | |
3196 | + } | |
3197 | + | |
3198 | + return s; | |
3199 | + } | |
3200 | + | |
3201 | + @Override | |
3202 | + public void onBypassFeedback(L2PcInstance player, String command) | |
3203 | + { | |
3204 | + if (command.startsWith("dungeon")) | |
3205 | + { | |
3206 | + | |
3207 | + | |
3208 | + if (DungeonManager.getInstance().isInDungeon(player) || player.isInOlympiadMode()) | |
3209 | + { | |
3210 | + player.sendMessage("You are currently unable to enter a Dungeon. Please try again later."); | |
3211 | + return; | |
3212 | + } | |
3213 | + | |
3214 | + if (player.isAio()) | |
3215 | + { | |
3216 | + player.sendMessage("AioBuffer: cannot leave You have been teleported to the nearest village."); | |
3217 | + return; | |
3218 | + } | |
3219 | + | |
3220 | + if (player.destroyItemByItemId("Donate Coin", Config.DUNGEON_COIN_ID, Config.CONT_DUNGEON_ITEM, null, true)) | |
3221 | + { | |
3222 | + int dungeonId = Integer.parseInt(command.substring(8)); | |
3223 | + | |
3224 | + if(dungeonId == 1 || dungeonId == 2) | |
3225 | + { | |
3226 | + DungeonManager.getInstance().enterDungeon(dungeonId, player); | |
3227 | + } | |
3228 | + | |
3229 | + else if (player.isOnline2()) | |
3230 | + { | |
3231 | + player.sendPacket(new ExShowScreenMessage("Your character Cont Item." +" "+ ItemTable.getInstance().getTemplate(Config.DUNGEON_COIN_ID).getName() + " " + Config.CONT_DUNGEON_ITEM , 6000, 2, true)); | |
3232 | + | |
3233 | + mainHtml(player, 0); | |
3234 | + } | |
3235 | + | |
3236 | + } | |
3237 | + else | |
3238 | + { | |
3239 | + mainHtml(player, 0); | |
3240 | + player.sendPacket(new ExShowScreenMessage("Your character Cont Item." +" "+ ItemTable.getInstance().getTemplate(Config.DUNGEON_COIN_ID).getName() + " " + Config.CONT_DUNGEON_ITEM , 6000, 2, true)); | |
3241 | + | |
3242 | + } | |
3243 | + } | |
3244 | + | |
3245 | + } | |
3246 | + | |
3247 | + public static void mainHtml(L2PcInstance activeChar, int time) | |
3248 | + { | |
3249 | + | |
3250 | + if (activeChar.isOnline2()) | |
3251 | + { | |
3252 | + NpcHtmlMessage nhm = new NpcHtmlMessage(5); | |
3253 | + StringBuilder html1 = new StringBuilder(""); | |
3254 | + html1.append("<html><head><title>Dungeon</title></head><body><center>"); | |
3255 | + html1.append("<br>"); | |
3256 | + html1.append("Your character Cont Item."); | |
3257 | + html1.append("</center>"); | |
3258 | + html1.append("</body></html>"); | |
3259 | + nhm.setHtml(html1.toString()); | |
3260 | + activeChar.sendPacket(nhm); | |
3261 | + } | |
3262 | + | |
3263 | + } | |
3264 | + | |
3265 | + @Override | |
3266 | + public void showChatWindow(L2PcInstance player, int val) | |
3267 | + { | |
3268 | + NpcHtmlMessage htm = new NpcHtmlMessage(getObjectId()); | |
3269 | + htm.setFile("data/html/mods/Dungeon-L2JDev/"+getNpcId()+(val == 0 ? "" : "-"+val)+".htm"); | |
3270 | + | |
3271 | + String[] s = htm.getHtml().split("%"); | |
3272 | + for (int i = 0; i < s.length; i++) | |
3273 | + { | |
3274 | + if (i % 2 > 0 && s[i].contains("dung ")) | |
3275 | + { | |
3276 | + StringTokenizer st = new StringTokenizer(s[i]); | |
3277 | + st.nextToken(); | |
3278 | + htm.replace("%"+s[i]+"%", getPlayerStatus(player, Integer.parseInt(st.nextToken()))); | |
3279 | + } | |
3280 | + } | |
3281 | + | |
3282 | + htm.replace("%objectId%", getObjectId()+""); | |
3283 | + | |
3284 | + player.sendPacket(htm); | |
3285 | + } | |
3286 | +} | |
3287 | ||
3288 | ||
3289 | ### Eclipse Workspace Patch 1.0 | |
3290 | #P L2jFrozen_GameServer | |
3291 | Index: head-src/com/l2jfrozen/gameserver/model/actor/instance/L2NpcInstance.java | |
3292 | =================================================================== | |
3293 | --- head-src/com/l2jfrozen/gameserver/model/actor/instance/L2NpcInstance.java (nonexistent) | |
3294 | +++ head-src/com/l2jfrozen/gameserver/model/actor/instance/L2NpcInstance.java (working copy) | |
3295 | import com.l2jfrozen.util.random.Rnd; | |
3296 | +import Base.Dev.Dungeon.Instance; | |
3297 | ||
3298 | ||
3299 | ||
3300 | ||
3301 | ||
3302 | /** | |
3303 | * Sets the custom npc instance. | |
3304 | * @param arg the new custom npc instance | |
3305 | */ | |
3306 | public void setCustomNpcInstance(final L2CustomNpcInstance arg) | |
3307 | { | |
3308 | _customNpcInstance = arg; | |
3309 | } | |
3310 | ||
3311 | /** | |
3312 | * Throws an action command to L2BufferTeonInstance.<br> | |
3313 | * @param player --> Target player | |
3314 | * @param buffTemplate --> Name of the Buff Template to Add | |
3315 | */ | |
3316 | public void makeBuffs(final L2PcInstance player, final String buffTemplate) | |
3317 | { | |
3318 | int _templateId = 0; | |
3319 | try | |
3320 | { | |
3321 | _templateId = Integer.parseInt(buffTemplate); | |
3322 | } | |
3323 | catch (final NumberFormatException e) | |
3324 | { | |
3325 | if (Config.ENABLE_ALL_EXCEPTIONS) | |
3326 | e.printStackTrace(); | |
3327 | ||
3328 | player.sendMessage("Buff ID doesn't exist"); | |
3329 | } | |
3330 | if (_templateId > 0) | |
3331 | { | |
3332 | L2BufferInstance.makeBuffs(player, _templateId, this, true); | |
3333 | this.updateEffectIcons(); | |
3334 | } | |
3335 | } | |
3336 | + /** | |
3337 | + * @param instance | |
3338 | + * @param b | |
3339 | + */ | |
3340 | + public void setInstance(Instance instance, boolean b) | |
3341 | + { | |
3342 | + return; | |
3343 | + } | |
3344 | ||
3345 | ||
3346 | ||
3347 | ### Eclipse Workspace Patch 1.0 | |
3348 | #P L2jFrozen_GameServer | |
3349 | Index: head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java | |
3350 | =================================================================== | |
3351 | --- head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java (nonexistent) | |
3352 | +++ head-src/com/l2jfrozen/gameserver/model/actor/instance/L2PcInstance.java (working copy) | |
3353 | ||
3354 | import com.l2jfrozen.util.random.Rnd; | |
3355 | +import Base.Dev.Dungeon.Dungeon; | |
3356 | +import Base.Dev.Dungeon.Instance; | |
3357 | +import Base.Manager.NewCharTaskManager; | |
3358 | +import Base.Memo.PlayerMemo; | |
3359 | +import Base.Util.Mysql; | |
3360 | ||
3361 | ||
3362 | ||
3363 | CursedWeaponsManager.getInstance().activate(this, item); | |
3364 | } | |
3365 | ||
3366 | item = null; | |
3367 | } | |
3368 | } | |
3369 | } | |
3370 | ||
3371 | /** | |
3372 | * Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance. | |
3373 | * @param process : String Identifier of process triggering this action | |
3374 | * @param itemId : int Item Identifier of the item to be added | |
3375 | * @param count : int Quantity of items to be added | |
3376 | * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation | |
3377 | * @param sendMessage : boolean Specifies whether to send message to Client about this action | |
3378 | * @return | |
3379 | */ | |
3380 | + public L2ItemInstance addItemDungeon(final String process, final int itemId, final int count, final L2Object reference, final boolean sendMessage) | |
3381 | + { | |
3382 | + if (count > 0) | |
3383 | + { | |
3384 | + // Retrieve the template of the item. | |
3385 | + final L2Item item = ItemTable.getInstance().getTemplate(itemId); | |
3386 | + if (item == null) | |
3387 | + { | |
3388 | + | |
3389 | + return null; | |
3390 | + } | |
3391 | + | |
3392 | + // Sends message to client if requested | |
3393 | + if (sendMessage && (!isCastingNow() && ItemTable.getInstance().createDummyItem(itemId).getItemType() == L2EtcItemType.HERB || ItemTable.getInstance().createDummyItem(itemId).getItemType() != L2EtcItemType.HERB)) | |
3394 | + { | |
3395 | + if (count > 1) | |
3396 | + { | |
3397 | + if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest")) | |
3398 | + { | |
3399 | + SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S); | |
3400 | + sm.addItemName(itemId); | |
3401 | + sm.addNumber(count); | |
3402 | + sendPacket(sm); | |
3403 | + sm = null; | |
3404 | + } | |
3405 | + else | |
3406 | + { | |
3407 | + SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2); | |
3408 | + sm.addItemName(itemId); | |
3409 | + sm.addNumber(count); | |
3410 | + sendPacket(sm); | |
3411 | + sm = null; | |
3412 | + } | |
3413 | + } | |
3414 | + else | |
3415 | + { | |
3416 | + if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest")) | |
3417 | + { | |
3418 | + SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_ITEM); | |
3419 | + sm.addItemName(itemId); | |
3420 | + sendPacket(sm); | |
3421 | + sm = null; | |
3422 | + } | |
3423 | + else | |
3424 | + { | |
3425 | + SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1); | |
3426 | + sm.addItemName(itemId); | |
3427 | + sendPacket(sm); | |
3428 | + sm = null; | |
3429 | + } | |
3430 | + } | |
3431 | + } | |
3432 | + // Auto use herbs - autoloot | |
3433 | + if (ItemTable.getInstance().createDummyItem(itemId).getItemType() == L2EtcItemType.HERB) // If item is herb dont add it to iv :] | |
3434 | + { | |
3435 | + if (!isCastingNow() && !isCastingPotionNow()) | |
3436 | + { | |
3437 | + L2ItemInstance herb = new L2ItemInstance(_charId, itemId); | |
3438 | + IItemHandler handler = ItemHandler.getInstance().getItemHandler(herb.getItemId()); | |
3439 | + | |
3440 | + if (handler == null) | |
3441 | + { | |
3442 | + LOGGER.warn("No item handler registered for Herb - item ID " + herb.getItemId() + "."); | |
3443 | + } | |
3444 | + else | |
3445 | + { | |
3446 | + handler.useItem(this, herb); | |
3447 | + | |
3448 | + if (_herbstask >= 100) | |
3449 | + { | |
3450 | + _herbstask -= 100; | |
3451 | + } | |
3452 | + | |
3453 | + handler = null; | |
3454 | + } | |
3455 | + | |
3456 | + herb = null; | |
3457 | + } | |
3458 | + else | |
3459 | + { | |
3460 | + _herbstask += 100; | |
3461 | + ThreadPoolManager.getInstance().scheduleAi(new HerbTask(process, itemId, count, reference, sendMessage), _herbstask); | |
3462 | + } | |
3463 | + } | |
3464 | + else | |
3465 | + { | |
3466 | + // Add the item to inventory | |
3467 | + L2ItemInstance createdItem = _inventory.addItem(process, itemId, count, this, reference); | |
3468 | + | |
3469 | + // Send inventory update packet | |
3470 | + if (!Config.FORCE_INVENTORY_UPDATE) | |
3471 | + { | |
3472 | + InventoryUpdate playerIU = new InventoryUpdate(); | |
3473 | + playerIU.addItem(createdItem); | |
3474 | + sendPacket(playerIU); | |
3475 | + playerIU = null; | |
3476 | + } | |
3477 | + else | |
3478 | + { | |
3479 | + sendPacket(new ItemList(this, false)); | |
3480 | + } | |
3481 | + | |
3482 | + // Update current load as well | |
3483 | + StatusUpdate su = new StatusUpdate(getObjectId()); | |
3484 | + su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad()); | |
3485 | + sendPacket(su); | |
3486 | + su = null; | |
3487 | + | |
3488 | + // If over capacity, drop the item | |
3489 | + if (!isGM() && !_inventory.validateCapacity(item)) | |
3490 | + { | |
3491 | + dropItem("InvDrop", createdItem, null, true, true); | |
3492 | + } | |
3493 | + else if (CursedWeaponsManager.getInstance().isCursed(createdItem.getItemId())) | |
3494 | + { | |
3495 | + CursedWeaponsManager.getInstance().activate(this, createdItem); | |
3496 | + } | |
3497 | + | |
3498 | + return createdItem; | |
3499 | + } | |
3500 | + } | |
3501 | + return null; | |
3502 | + } | |
3503 | ||
3504 | ||
3505 | ||
3506 | ||
3507 | ||
3508 | ||
3509 | /** | |
3510 | * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance. | |
3511 | * @param process : String Identifier of process triggering this action | |
3512 | * @param item : L2ItemInstance to be destroyed | |
3513 | * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation | |
3514 | * @param sendMessage : boolean Specifies whether to send message to Client about this action | |
3515 | * @return boolean informing if the action was successfull | |
3516 | */ | |
3517 | public boolean destroyItem(final String process, L2ItemInstance item, final L2Object reference, final boolean sendMessage) | |
3518 | { | |
3519 | ||
3520 | ||
3521 | ||
3522 | ||
3523 | ||
3524 | ||
3525 | ||
3526 | ||
3527 | ||
3528 | ||
3529 | ||
3530 | ||
3531 | ||
3532 | ||
3533 | ||
3534 | ||
3535 | ||
3536 | ||
3537 | ||
3538 | /** The _original karma vip. */ | |
3539 | public int _originalNameColourVIP, _originalKarmaVIP; | |
3540 | ||
3541 | ||
3542 | + private final PlayerMemo _vars2 = new PlayerMemo(getObjectId()); | |
3543 | ||
3544 | ||
3545 | ||
3546 | ||
3547 | else if (CursedWeaponsManager.getInstance().isCursed(newitem.getItemId())) | |
3548 | { | |
3549 | CursedWeaponsManager.getInstance().activate(this, newitem); | |
3550 | } | |
3551 | newitem = null; | |
3552 | } | |
3553 | + if (isNewChar()) | |
3554 | + NewCharTaskManager.getInstance().add(this); | |
3555 | ||
3556 | ||
3557 | ||
3558 | ||
3559 | ||
3560 | ||
3561 | ||
3562 | ||
3563 | ||
3564 | ||
3565 | ||
3566 | ||
3567 | ||
3568 | ||
3569 | ||
3570 | ||
3571 | ||
3572 | ||
3573 | /** | |
3574 | * Update L2PcInstance stats in the characters table of the database.<BR> | |
3575 | * <BR> | |
3576 | */ | |
3577 | public synchronized void store() | |
3578 | { | |
3579 | store(false); | |
3580 | } | |
3581 | ||
3582 | + /** | |
3583 | + * @return player memos. | |
3584 | + */ | |
3585 | + public PlayerMemo getMemos() | |
3586 | + { | |
3587 | + return _vars2; | |
3588 | + } | |
3589 | + | |
3590 | + | |
3591 | + | |
3592 | + public String getIP() | |
3593 | + { | |
3594 | + if (getClient().getConnection() == null) | |
3595 | + return "N/A IP"; | |
3596 | + | |
3597 | + return getClient().getConnection().getInetAddress().getHostAddress(); | |
3598 | + } | |
3599 | + | |
3600 | + | |
3601 | + public static void doNewChar(L2PcInstance player, int time) | |
3602 | + { | |
3603 | + player.setNewChar(true); | |
3604 | + NewCharTaskManager.getInstance().add(player); | |
3605 | + long remainingTime = player.getMemos().getLong("newEndTime", 0); | |
3606 | + if (remainingTime > 0) | |
3607 | + { | |
3608 | + player.getMemos().set("newEndTime", remainingTime + TimeUnit.MINUTES.toMillis(time)); | |
3609 | + } | |
3610 | + else | |
3611 | + { | |
3612 | + player.getMemos().set("newEndTime", System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(time)); | |
3613 | + player.broadcastUserInfo(); | |
3614 | + } | |
3615 | + } | |
3616 | + | |
3617 | + public static void removeNewChar(L2PcInstance player) | |
3618 | + { | |
3619 | + NewCharTaskManager.getInstance().remove(player); | |
3620 | + player.getMemos().set("newEndTime", 0); | |
3621 | + player.setNewChar(false); | |
3622 | + player.broadcastUserInfo(); | |
3623 | + | |
3624 | + } | |
3625 | + private boolean _isnewChar; | |
3626 | + public boolean isNewChar() | |
3627 | + { | |
3628 | + return _isnewChar; | |
3629 | + } | |
3630 | + | |
3631 | + public void setNewChar(boolean b) | |
3632 | + { | |
3633 | + _isnewChar = b; | |
3634 | + } | |
3635 | + private Dungeon dungeon = null; | |
3636 | + public void setDungeon(Dungeon val) | |
3637 | + { | |
3638 | + dungeon = val; | |
3639 | + } | |
3640 | + | |
3641 | + public Dungeon getDungeon() | |
3642 | + { | |
3643 | + return dungeon; | |
3644 | + } | |
3645 | + | |
3646 | + public void deleteTempItem(int itemObjectID) | |
3647 | + { | |
3648 | + boolean destroyed = false; | |
3649 | + if (getInventory().getItemByObjectId(itemObjectID) != null) | |
3650 | + { | |
3651 | + sendMessage("Your "+ItemTable.getInstance().getTemplate(getInventory().getItemByObjectId(itemObjectID).getItemId()).getName()+" has expired."); | |
3652 | + destroyItem("tempItemDestroy", itemObjectID, 1, this, true); | |
3653 | + getInventory().updateDatabase(); | |
3654 | + sendPacket(new ItemList(this, true)); | |
3655 | + | |
3656 | + destroyed = true; | |
3657 | + } | |
3658 | + | |
3659 | + if (!destroyed) | |
3660 | + { | |
3661 | + Connection con = null; | |
3662 | + PreparedStatement statement = null; | |
3663 | + ResultSet rset = null; | |
3664 | + try | |
3665 | + { | |
3666 | + con = L2DatabaseFactory.getInstance().getConnection(); | |
3667 | + statement = con.prepareStatement("DELETE FROM items WHERE object_id=?"); | |
3668 | + statement.setInt(1, itemObjectID); | |
3669 | + statement.execute(); | |
3670 | + } | |
3671 | + catch (Exception e) | |
3672 | + { | |
3673 | + e.printStackTrace(); | |
3674 | + } | |
3675 | + finally | |
3676 | + { | |
3677 | + Mysql.closeQuietly(con, statement, rset); | |
3678 | + } | |
3679 | + } | |
3680 | + } | |
3681 | + private boolean _isInClanDungeonZone; | |
3682 | + public boolean isInClanDungeonZone() | |
3683 | + { | |
3684 | + return _isInClanDungeonZone; | |
3685 | + } | |
3686 | + | |
3687 | + public void setClanDungeonZone(boolean isInClanDungeonZone) | |
3688 | + { | |
3689 | + _isInClanDungeonZone = isInClanDungeonZone; | |
3690 | + } | |
3691 | + /** | |
3692 | + * @param instance | |
3693 | + * @param b | |
3694 | + */ | |
3695 | + public void setInstance(Instance instance, boolean b) | |
3696 | + { | |
3697 | + return; | |
3698 | + | |
3699 | + } | |
3700 | + | |
3701 | + public final void broadcastCharInfo() | |
3702 | + { | |
3703 | + for (L2PcInstance player : getKnownList().getKnownType(L2PcInstance.class)) | |
3704 | + { | |
3705 | + player.sendPacket(new CharInfo(this)); | |
3706 | + | |
3707 | + final int relation = getRelation(player); | |
3708 | + player.sendPacket(new RelationChanged(this, relation, isAutoAttackable(player))); | |
3709 | + if (getPet() != null) | |
3710 | + player.sendPacket(new RelationChanged(getPet(), relation, isAutoAttackable(player))); | |
3711 | + } | |
3712 | + } | |
3713 | + | |
3714 | + /** | |
3715 | + * @return True if the Player is online. | |
3716 | + */ | |
3717 | + public boolean isOnline2() | |
3718 | + { | |
3719 | + return _isOnline; | |
3720 | + } | |
3721 | + | |
3722 | ||
3723 | ### Eclipse Workspace Patch 1.0 | |
3724 | #P L2jFrozen_GameServer | |
3725 | Index: head-src/com/l2jfrozen/gameserver/model/L2Character.java | |
3726 | =================================================================== | |
3727 | --- head-src/com/l2jfrozen/gameserver/model/L2Character.java (nonexistent) | |
3728 | +++ head-src/com/l2jfrozen/gameserver/model/L2Character.java (working copy) | |
3729 | ||
3730 | /** The _last skill cast. */ | |
3731 | private L2Skill _lastSkillCast; | |
3732 | ||
3733 | + protected boolean _showSummonAnimation = false; | |
3734 | ||
3735 | ||
3736 | ||
3737 | ||
3738 | ||
3739 | ||
3740 | ||
3741 | ||
3742 | ||
3743 | ||
3744 | ||
3745 | ||
3746 | ||
3747 | synchronized public void reloadShots(final boolean isMagic) | |
3748 | { | |
3749 | if (this instanceof L2PcInstance) | |
3750 | { | |
3751 | ((L2PcInstance) this).rechargeAutoSoulShot(!isMagic, isMagic, false); | |
3752 | } | |
3753 | else if (this instanceof L2Summon) | |
3754 | { | |
3755 | ((L2Summon) this).getOwner().rechargeAutoSoulShot(!isMagic, isMagic, true); | |
3756 | } | |
3757 | } | |
3758 | ||
3759 | + public void teleToLocation(int x, int y, int z, int randomOffset) | |
3760 | + { | |
3761 | + // Stop movement | |
3762 | + stopMove(null); | |
3763 | + abortAttack(); | |
3764 | + abortCast(); | |
3765 | + | |
3766 | + setIsTeleporting(true); | |
3767 | + setTarget(null); | |
3768 | + | |
3769 | + getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); | |
3770 | + | |
3771 | + if (randomOffset > 0) | |
3772 | + { | |
3773 | + x += Rnd.get(-randomOffset, randomOffset); | |
3774 | + y += Rnd.get(-randomOffset, randomOffset); | |
3775 | + } | |
3776 | + | |
3777 | + z += 5; | |
3778 | + | |
3779 | + // Send TeleportToLocationt to the L2Character AND to all Player in the _KnownPlayers of the L2Character | |
3780 | + broadcastPacket(new TeleportToLocation(this, x, y, z)); | |
3781 | + | |
3782 | + // remove the object from its old location | |
3783 | + decayMe(); | |
3784 | + | |
3785 | + // Set the x,y,z position of the L2Object and if necessary modify its _worldRegion | |
3786 | + getPosition().setXYZ(x, y, z); | |
3787 | + | |
3788 | + if (!(this instanceof L2PcInstance) || (((L2PcInstance) this).getClient() != null && ((L2PcInstance) | |
3789 | + this).getClient().isDetached())) | |
3790 | + onTeleported(); | |
3791 | + | |
3792 | + revalidateZone(true); | |
3793 | + } | |
3794 | + | |
3795 | + public void teleToLocation(Location loc, int randomOffset) | |
3796 | + { | |
3797 | + int x = loc.getX(); | |
3798 | + int y = loc.getY(); | |
3799 | + int z = loc.getZ(); | |
3800 | + | |
3801 | + if (this instanceof L2PcInstance && DimensionalRiftManager.getInstance().checkIfInRiftZone(getX(), getY(), getZ(), true)) // | |
3802 | + true -> ignore waiting room :) | |
3803 | + { | |
3804 | + L2PcInstance player = (L2PcInstance) this; | |
3805 | + player.sendMessage("You have been sent to the waiting room."); | |
3806 | + if (player.isInParty() && player.getParty().isInDimensionalRift()) | |
3807 | + { | |
3808 | + player.getParty().getDimensionalRift().usedTeleport(player); | |
3809 | + } | |
3810 | + int[] newCoords = DimensionalRiftManager.getInstance().getRoom((byte) 0, (byte) 0).getTeleportCoords(); | |
3811 | + x = newCoords[0]; | |
3812 | + y = newCoords[1]; | |
3813 | + z = newCoords[2]; | |
3814 | + } | |
3815 | + teleToLocation(x, y, z, randomOffset); | |
3816 | + } | |
3817 | + | |
3818 | + public void teleToLocation2(TeleportWhereType teleportWhere) | |
3819 | + { | |
3820 | + teleToLocation(MapRegionTable.getInstance().getTeleToLocation(this, teleportWhere), 20); | |
3821 | + } | |
3822 | ||
3823 | + /** | |
3824 | + * @return Returns the showSummonAnimation. | |
3825 | + */ | |
3826 | + public boolean isShowSummonAnimation() | |
3827 | + { | |
3828 | + return _showSummonAnimation; | |
3829 | + } | |
3830 | + | |
3831 | + /** | |
3832 | + * @param showSummonAnimation The showSummonAnimation to set. | |
3833 | + */ | |
3834 | + public void setShowSummonAnimation(boolean showSummonAnimation) | |
3835 | + { | |
3836 | + _showSummonAnimation = showSummonAnimation; | |
3837 | + } | |
3838 | ||
3839 | ||
3840 | ||
3841 | ### Eclipse Workspace Patch 1.0 | |
3842 | #P L2jFrozen_GameServer | |
3843 | Index: head-src/com/l2jfrozen/gameserver/model/spawn/L2Spawn.java | |
3844 | =================================================================== | |
3845 | --- head-src/com/l2jfrozen/gameserver/model/spawn/L2Spawn.java (nonexistent) | |
3846 | +++ head-src/com/l2jfrozen/gameserver/model/spawn/L2Spawn.java (working copy) | |
3847 | public L2NpcTemplate getTemplate() | |
3848 | { | |
3849 | return _template; | |
3850 | } | |
3851 | ||
3852 | public int getInstanceId() | |
3853 | { | |
3854 | return _instanceId; | |
3855 | } | |
3856 | ||
3857 | public void setInstanceId(final int instanceId) | |
3858 | { | |
3859 | _instanceId = instanceId; | |
3860 | } | |
3861 | ||
3862 | + public L2NpcInstance doSpawn(boolean isSummonSpawn) | |
3863 | + { | |
3864 | + L2NpcInstance mob = null; | |
3865 | + try | |
3866 | + { | |
3867 | + // Check if the L2Spawn is not a L2Pet or L2Minion | |
3868 | + if (_template.isType("L2Pet") || _template.isType("L2Minion")) | |
3869 | + return mob; | |
3870 | + | |
3871 | + // Get L2Npc Init parameters and its generate an Identifier | |
3872 | + Object[] parameters = | |
3873 | + { | |
3874 | + IdFactory.getInstance().getNextId(), | |
3875 | + _template | |
3876 | + }; | |
3877 | + | |
3878 | + // Call the constructor of the L2Npc | |
3879 | + // (can be a L2ArtefactInstance, L2FriendlyMobInstance, L2GuardInstance, L2MonsterInstance, L2SiegeGuardInstance, L2BoxInstance, | |
3880 | + // L2FeedableBeastInstance, L2TamedBeastInstance, L2NpcInstance) | |
3881 | + Object tmp = _constructor.newInstance(parameters); | |
3882 | + | |
3883 | + if (isSummonSpawn && tmp instanceof L2Character) | |
3884 | + ((L2Character) tmp).setShowSummonAnimation(isSummonSpawn); | |
3885 | + | |
3886 | + // Check if the Instance is a L2Npc | |
3887 | + if (!(tmp instanceof L2NpcInstance)) | |
3888 | + return mob; | |
3889 | + | |
3890 | + mob = (L2NpcInstance) tmp; | |
3891 | + return intializeNpcInstance(mob); | |
3892 | + } | |
3893 | + catch (Exception e) | |
3894 | + { | |
3895 | + | |
3896 | + } | |
3897 | + return mob; | |
3898 | + } | |
3899 | + | |
3900 | + /** | |
3901 | + * @return | |
3902 | + */ | |
3903 | + public L2NpcInstance getNpc() | |
3904 | + { | |
3905 | + return _lastSpawn; | |
3906 | + } | |
3907 | ||
3908 | ### Eclipse Workspace Patch 1.0 | |
3909 | #P L2jFrozen_GameServer | |
3910 | Index: head-src/com/l2jfrozen/gameserver/templates/L2NpcTemplate.java | |
3911 | =================================================================== | |
3912 | --- head-src/com/l2jfrozen/gameserver/templates/L2NpcTemplate.java (nonexistent) | |
3913 | +++ head-src/com/l2jfrozen/gameserver/templates/L2NpcTemplate.java (working copy) | |
3914 | ||
3915 | public final String type; | |
3916 | + private final String _type; | |
3917 | ||
3918 | ||
3919 | ||
3920 | type = set.getString("type"); | |
3921 | + _type = set.getString("type"); | |
3922 | ||
3923 | ||
3924 | ||
3925 | ||
3926 | public final boolean isCustom() | |
3927 | { | |
3928 | return _custom; | |
3929 | } | |
3930 | ||
3931 | + /** | |
3932 | + * Checks types, ignore case. | |
3933 | + * @param t the type to check. | |
3934 | + * @return true if the type are the same, false otherwise. | |
3935 | + */ | |
3936 | + public boolean isType(String t) | |
3937 | + { | |
3938 | + return _type.equalsIgnoreCase(t); | |
3939 | + } | |
3940 | ||
3941 | ||
3942 | ||
3943 | ### Eclipse Workspace Patch 1.0 | |
3944 | #P L2jFrozen_GameServer | |
3945 | Index: head-src/com/l2jfrozen/gameserver/network/clientpackets/EnterWorld.java | |
3946 | =================================================================== | |
3947 | --- head-src/com/l2jfrozen/gameserver/network/clientpackets/EnterWorld.java (nonexistent) | |
3948 | +++ head-src/com/l2jfrozen/gameserver/network/clientpackets/EnterWorld.java (working copy) | |
3949 | ||
3950 | @Override | |
3951 | protected void runImpl() | |
3952 | { | |
3953 | final L2PcInstance activeChar = getClient().getActiveChar(); | |
3954 | ||
3955 | if (activeChar == null) | |
3956 | { | |
3957 | LOGGER.warn("EnterWorld failed! activeChar is null..."); | |
3958 | getClient().closeNow(); | |
3959 | return; | |
3960 | } | |
3961 | ||
3962 | + // Set NewChar | |
3963 | + switch (activeChar.getClassId().getId()) | |
3964 | + { | |
3965 | + case 0: | |
3966 | + case 10: | |
3967 | + case 18: | |
3968 | + case 25: | |
3969 | + case 31: | |
3970 | + case 38: | |
3971 | + case 44: | |
3972 | + case 49: | |
3973 | + case 53: | |
3974 | + L2PcInstance.doNewChar(activeChar, 1); | |
3975 | + break; | |
3976 | + } | |
3977 | ||
3978 | ||
3979 | ||
3980 | ||
3981 | ||
3982 | ||
3983 | ||
3984 | EnterGM(activeChar); | |
3985 | ||
3986 | + if (activeChar.getMemos().getLong("newEndTime", 0) > 0) | |
3987 | + onEnterNewChar(activeChar); | |
3988 | ||
3989 | ||
3990 | ||
3991 | ||
3992 | ||
3993 | private void onEnterAio(final L2PcInstance activeChar) | |
3994 | { | |
3995 | final long now = Calendar.getInstance().getTimeInMillis(); | |
3996 | final long endDay = activeChar.getAioEndTime(); | |
3997 | ||
3998 | if (now > endDay) | |
3999 | { | |
4000 | activeChar.setAio(false); | |
4001 | activeChar.setAioEndTime(0); | |
4002 | activeChar.lostAioSkills(); | |
4003 | activeChar.sendMessage("[Aio System]: Removed your Aio stats... period ends."); | |
4004 | } | |
4005 | else | |
4006 | { | |
4007 | final Date dt = new Date(endDay); | |
4008 | _daysleft = (endDay - now) / 86400000; | |
4009 | if (_daysleft > 30) | |
4010 | activeChar.sendMessage("[Aio System]: Aio period ends in " + df.format(dt) + ". enjoy the Game."); | |
4011 | else if (_daysleft > 0) | |
4012 | activeChar.sendMessage("[Aio System]: Left " + (int) _daysleft + " for Aio period ends."); | |
4013 | else if (_daysleft < 1) | |
4014 | { | |
4015 | final long hour = (endDay - now) / 3600000; | |
4016 | activeChar.sendMessage("[Aio System]: Left " + (int) hour + " hours to Aio period ends."); | |
4017 | } | |
4018 | } | |
4019 | } | |
4020 | ||
4021 | + private static void onEnterNewChar(L2PcInstance activeChar) | |
4022 | + { | |
4023 | + long now = Calendar.getInstance().getTimeInMillis(); | |
4024 | + long endDay = activeChar.getMemos().getLong("newEndTime"); | |
4025 | + | |
4026 | + if (now > endDay) | |
4027 | + L2PcInstance.removeNewChar(activeChar); | |
4028 | + else | |
4029 | + { | |
4030 | + activeChar.setNewChar(true); | |
4031 | + activeChar.broadcastUserInfo(); | |
4032 | + } | |
4033 | + } | |
4034 | ||
4035 | ||
4036 | ||
4037 | /** | |
4038 | * @param cha | |
4039 | */ | |
4040 | private void engage(final L2PcInstance cha) | |
4041 | ||
4042 | ||
4043 | ||
4044 | ||
4045 | ### Eclipse Workspace Patch 1.0 | |
4046 | #P L2jFrozen_GameServer | |
4047 | Index: head-src/com/l2jfrozen/gameserver/network/clientpackets/RequestBypassToServer.java | |
4048 | =================================================================== | |
4049 | --- head-src/com/l2jfrozen/gameserver/network/clientpackets/RequestBypassToServer.java (nonexistent) | |
4050 | +++ head-src/com/l2jfrozen/gameserver/network/clientpackets/RequestBypassToServer.java (working copy) | |
4051 | import com.l2jterius.gameserver.model.actor.instance.L2ClassMasterInstance; | |
4052 | +import com.l2jterius.gameserver.model.actor.instance.L2ItemInstance; | |
4053 | ||
4054 | ||
4055 | ||
4056 | ||
4057 | import com.l2jfrozen.gameserver.util.GMAudit; | |
4058 | +import Base.Dev.Dungeon.InstanceManager; | |
4059 | +import Base.Memo.PlayerMemo; | |
4060 | ||
4061 | ||
4062 | ||
4063 | ||
4064 | else if (_command.startsWith("player_help ")) | |
4065 | { | |
4066 | playerHelp(activeChar, _command.substring(12)); | |
4067 | } | |
4068 | ||
4069 | ||
4070 | + if (_command.startsWith("bp_reward")) | |
4071 | + { | |
4072 | + int type = Integer.parseInt(_command.substring(10)); | |
4073 | + int itemId = 0; | |
4074 | + int count = 1; | |
4075 | + | |
4076 | + switch (type) | |
4077 | + { | |
4078 | + case 0: | |
4079 | + { | |
4080 | + itemId = Config.DUNGEON_ITEM_RENEWAL0; | |
4081 | + | |
4082 | + break; | |
4083 | + } | |
4084 | + case 1: | |
4085 | + { | |
4086 | + itemId = Config.DUNGEON_ITEM_RENEWAL1; | |
4087 | + | |
4088 | + break; | |
4089 | + } | |
4090 | + case 2: | |
4091 | + { | |
4092 | + itemId = Config.DUNGEON_ITEM_RENEWAL2; | |
4093 | + | |
4094 | + break; | |
4095 | + } | |
4096 | + case 3: | |
4097 | + { | |
4098 | + itemId = Config.DUNGEON_ITEM_RENEWAL3; | |
4099 | + | |
4100 | + break; | |
4101 | + } | |
4102 | + case 4: | |
4103 | + { | |
4104 | + itemId = Config.DUNGEON_ITEM_RENEWAL4; | |
4105 | + | |
4106 | + break; | |
4107 | + } | |
4108 | + case 5: | |
4109 | + { | |
4110 | + itemId = Config.DUNGEON_ITEM_RENEWAL5; | |
4111 | + | |
4112 | + break; | |
4113 | + } | |
4114 | + case 6: | |
4115 | + { | |
4116 | + itemId = Config.DUNGEON_ITEM_RENEWAL6; | |
4117 | + | |
4118 | + break; | |
4119 | + } | |
4120 | + case 7: | |
4121 | + { | |
4122 | + itemId = Config.DUNGEON_ITEM_RENEWAL7; | |
4123 | + | |
4124 | + break; | |
4125 | + } | |
4126 | + case 8: | |
4127 | + { | |
4128 | + itemId = Config.DUNGEON_ITEM_RENEWAL8; | |
4129 | + | |
4130 | + break; | |
4131 | + } | |
4132 | + case 9: | |
4133 | + { | |
4134 | + itemId = Config.DUNGEON_ITEM_RENEWAL9; | |
4135 | + | |
4136 | + break; | |
4137 | + } | |
4138 | + case 10: | |
4139 | + { | |
4140 | + itemId = Config.DUNGEON_ITEM_RENEWAL10; | |
4141 | + | |
4142 | + break; | |
4143 | + } | |
4144 | + } | |
4145 | + | |
4146 | + if (itemId == 0) | |
4147 | + { | |
4148 | + System.out.println(activeChar.getName() + " tried to send custom id on dungeon solo rewards."); | |
4149 | + return; | |
4150 | + } | |
4151 | + if(activeChar.getDungeon() != null) | |
4152 | + { | |
4153 | + L2ItemInstance item = activeChar.addItemDungeon("dungeon reward", itemId, count, null, true); | |
4154 | + item.setEnchantLevel(25); | |
4155 | + activeChar.getInventory().equipItemAndRecord(item); | |
4156 | + PlayerMemo.setVar(activeChar, "delete_temp_item_" + item.getObjectId(), item.getObjectId(), System.currentTimeMillis() + (1000 *60 *60 *5)); | |
4157 | + InstanceManager.getInstance().getInstance(0); | |
4158 | + activeChar.setDungeon(null); | |
4159 | + activeChar.teleToLocation(Config.DUNGEON_SPAWN_X, Config.DUNGEON_SPAWN_Y, Config.DUNGEON_SPAWN_Z, Config.DUNGEON_SPAWN_RND); | |
4160 | + } | |
4161 | + else | |
4162 | + { | |
4163 | + activeChar.sendMessage("No puedes recibir el premio"); | |
4164 | + } | |
4165 | + } | |
4166 | ||
4167 | else if (_command.startsWith("npc_")) | |
4168 | ||
4169 | ||
4170 | ||
4171 | ### Eclipse Workspace Patch 1.0 | |
4172 | #P L2jFrozen_GameServer | |
4173 | Index: Frozen 1132\gameserver\events\Dungeon.xml | |
4174 | =================================================================== | |
4175 | --- Frozen 1132\gameserver\events\Dungeon.xml (nonexistent) | |
4176 | +++ Frozen 1132\gameserver\events\Dungeon.xml (working copy) | |
4177 | +<?xml version="1.0" encoding="UTF-8"?> | |
4178 | +<list> | |
4179 | + <dungeon id="1" name="Solo Story Mode" players="1" rewards="57,200000" rewardHtm="data/html/mods/Dungeon-L2JDev/solo_rewards.htm"> | |
4180 | + <stage order="1" loc="174122,-76173,-5106" teleport="true" minutes="5"> | |
4181 | + <mob npcId="65515" locs="174527,-75636,-5106;174654,-75987,-5106;174647,-76483,-5106;174160,-76758,-5106"/> | |
4182 | + </stage> | |
4183 | + <stage order="2" loc="174082,-78151,-5106" teleport="false" minutes="5"> | |
4184 | + <mob npcId="65515" locs="174527,-75636,-5106;174654,-75987,-5106;174647,-76483,-5106;174160,-76758,-5106"/> | |
4185 | + </stage> | |
4186 | + <stage order="3" loc="174038,-80727,-5106" teleport="true" minutes="5"> | |
4187 | + <mob npcId="65515" locs="173739,-81254,-5122;173736,-81613,-5122;173729,-82232,-5122;174041,-82539,-5122;174377,-82379,-5122;174451,-81893,-5122;174433,-81342,-5122;174152,-81560,-5122"/> | |
4188 | + </stage> | |
4189 | + <stage order="4" loc="174230,-87512,-5116" teleport="true" minutes="15"> | |
4190 | + <mob npcId="65515" locs="174229,-86659,-5106"/> | |
4191 | + </stage> | |
4192 | + </dungeon> | |
4193 | + <dungeon id="2" name="Quatro Hard Mode" players="4" rewards="57,1000000" rewardHtm="NULL"> | |
4194 | + <stage order="1" loc="174122,-76173,-5106" teleport="true" minutes="5"> | |
4195 | + <mob npcId="65515" locs="174527,-75636,-5106;174654,-75987,-5106;174647,-76483,-5106;174160,-76758,-5106"/> | |
4196 | + </stage> | |
4197 | + <stage order="2" loc="174082,-78151,-5106" teleport="false" minutes="5"> | |
4198 | + <mob npcId="65515" locs="174527,-75636,-5106;174654,-75987,-5106;174647,-76483,-5106;174160,-76758,-5106"/> | |
4199 | + </stage> | |
4200 | + <stage order="3" loc="174038,-80727,-5106" teleport="true" minutes="5"> | |
4201 | + <mob npcId="65515" locs="173739,-81254,-5122;173736,-81613,-5122;173729,-82232,-5122;174041,-82539,-5122;174377,-82379,-5122;174451,-81893,-5122;174433,-81342,-5122;174152,-81560,-5122"/> | |
4202 | + </stage> | |
4203 | + <stage order="4" loc="174056,-83856,-5106" teleport="true" minutes="5"> | |
4204 | + <mob npcId="65515" locs="174742,-84194,-5106;174745,-84526,-5106;174726,-85127,-5106;174231,-85361,-5106"/> | |
4205 | + </stage> | |
4206 | + <stage order="5" loc="174229,-86659,-5106" teleport="true" minutes="5"> | |
4207 | + <mob npcId="65515" locs="174742,-84194,-5106;174745,-84526,-5106;174726,-85127,-5106;174231,-85361,-5106"/> | |
4208 | + </stage> | |
4209 | + <stage order="6" loc="174229,-86659,-5106" teleport="false" minutes="5"> | |
4210 | + <mob npcId="65515" locs="174229,-86659,-5106"/> | |
4211 | + </stage> | |
4212 | + <stage order="7" loc="174229,-86659,-5106" teleport="false" minutes="10"> | |
4213 | + <mob npcId="65515" locs="174229,-86659,-5106"/> | |
4214 | + </stage> | |
4215 | + </dungeon> | |
4216 | +</list> | |
4217 | ||
4218 | ||
4219 | ### Eclipse Workspace Patch 1.0 | |
4220 | #P L2jFrozen_GameServer | |
4221 | Index: Frozen 1132\gameserver\events\Dungeon_Html_Reward.properties | |
4222 | =================================================================== | |
4223 | --- Frozen 1132\gameserver\events\Dungeon_Html_Reward.properties (nonexistent) | |
4224 | +++ Frozen 1132\gameserver\events\Dungeon_Html_Reward.properties (working copy) | |
4225 | +#Item Id Prince L2DungeonManager | |
4226 | +DungeonCoinId = 57 | |
4227 | +# ID of the item that will be Buy to Dungeon | |
4228 | +DungeonContItem = 1 | |
4229 | +#Cordenadas para la vuelta del jugador al terminar el evento Idea por: jeriko90 | |
4230 | +DungeonSpawnX = 82732 | |
4231 | +DungeonSpawnY = 149316 | |
4232 | +DungeonSpawnZ = -3495 | |
4233 | +DungeonSpawnRnd = 25 | |
4234 | + | |
4235 | +#Renewal Dungeon Open Html Finishi! | |
4236 | +DungeonRenewalHtml0 = 6657 | |
4237 | +DungeonRenewalHtml1 = 6656 | |
4238 | +DungeonRenewalHtml2 = 6658 | |
4239 | +DungeonRenewalHtml3 = 6659 | |
4240 | +DungeonRenewalHtml4 = 6660 | |
4241 | +DungeonRenewalHtml5 = 8191 | |
4242 | +DungeonRenewalHtml6 = 49997 | |
4243 | +DungeonRenewalHtml7 = 49998 | |
4244 | +DungeonRenewalHtml8 = 50000 | |
4245 | +DungeonRenewalHtml9 = 59989 | |
4246 | +DungeonRenewalHtml10 = 52366 | |
4247 | ||
4248 | ||
4249 | ||
4250 | ||
4251 | ||
4252 | ||
4253 | Custom_Npc.sql | |
4254 | ||
4255 | INSERT INTO `custom_npc` VALUES ('65514', '31228', 'Dungeon Manager', '1', 'L2J-FROZEN', '1', 'Monster.cat_the_cat', '9.00', '16.00', '70', 'male', 'L2DungeonManager', '40', '3862', '1493', '11.85', '2.78', '40', '43', '30', '21', '20', '10', '490', '10', '1335', '470', '780', '382', '278', '0', '333', '0', '0', '0', '88', '132', '', '0', '0', '0', 'LAST_HIT'); | |
4256 | INSERT INTO `custom_npc` VALUES ('65515', '29031', 'Dungeon Mob', '1', '', '0', 'Monster2.ifrit', '10.00', '42.00', '80', 'male', 'L2DungeonMob', '40', '33984', '1859', '55.62', '4.16', '40', '43', '30', '21', '20', '10', '0', '0', '10275', '2307', '6886', '937', '278', '0', '333', '0', '0', '0', '41', '187', 'fire_clan', '300', '0', '0', 'LAST_HIT'); | |
4257 | ||
4258 | ||
4259 | ||
4260 | ||
4261 |