/* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ package com.l2jserver.gameserver.model.olympiad; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.olympiad.Olympiad.COMP_TYPE; import com.l2jserver.util.L2FastList; import com.l2jserver.util.Rnd; import javolution.util.FastMap; /** * * @author GodKratos */ class OlympiadManager implements Runnable { protected static final Logger _log = Logger.getLogger(OlympiadManager.class.getName()); private Map _olympiadInstances; protected static final OlympiadStadium[] STADIUMS = { new OlympiadStadium(-88000, -252637, -3331, 17100001, 17100002), new OlympiadStadium(-83760, -252637, -3331, 17100003, 17100004), new OlympiadStadium(-79600, -252637, -3331, 17100005, 17100006), new OlympiadStadium(-75648, -252637, -3331, 17100007, 17100008), new OlympiadStadium(-88000, -249762, -3331, 17100009, 17100010), new OlympiadStadium(-83760, -249762, -3331, 17100011, 17100012), new OlympiadStadium(-79600, -249762, -3331, 17100013, 17100014), new OlympiadStadium(-75648, -249762, -3331, 17100015, 17100016), new OlympiadStadium(-88000, -246951, -3331, 17100017, 17100018), new OlympiadStadium(-83760, -246951, -3331, 17100019, 17100020), new OlympiadStadium(-79600, -246951, -3331, 17100021, 17100022), new OlympiadStadium(-75648, -246951, -3331, 17100023, 17100024), new OlympiadStadium(-88000, -244290, -3331, 17100025, 17100026), new OlympiadStadium(-83760, -244290, -3331, 17100027, 17100028), new OlympiadStadium(-79600, -244290, -3331, 17100029, 17100030), new OlympiadStadium(-75648, -244290, -3331, 17100031, 17100032), new OlympiadStadium(-88000, -241490, -3331, 17100033, 17100034), new OlympiadStadium(-83760, -241490, -3331, 17100035, 17100036), new OlympiadStadium(-79600, -241490, -3331, 17100037, 17100038), new OlympiadStadium(-75648, -241490, -3331, 17100039, 17100040), new OlympiadStadium(-88000, -238825, -3331, 17100041, 17100042), new OlympiadStadium(-83760, -238825, -3331, 17100043, 17100044) }; private OlympiadManager() { _olympiadInstances = new FastMap(); } public static OlympiadManager getInstance() { return SingletonHolder._instance; } public synchronized void run() { if (Olympiad.getInstance().isOlympiadEnd()) return; Map _gamesQueue = new FastMap(); while (Olympiad.getInstance().inCompPeriod()) { if (Olympiad.getNobleCount() == 0) { try { wait(60000); } catch (InterruptedException ex) { return; } continue; } int _gamesQueueSize = 0; // _compStarted = true; L2FastList readyClasses = Olympiad.hasEnoughRegisteredClassed(); boolean readyNonClassed = Olympiad.hasEnoughRegisteredNonClassed(); if (readyClasses != null || readyNonClassed) { // set up the games queue for (int i = 0; i < STADIUMS.length; i++) { if (!existNextOpponents(Olympiad.getRegisteredNonClassBased()) && !existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))) { break; } if (STADIUMS[i].isFreeToUse()) { if (i < STADIUMS.length / 2) { if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased())) { try { _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased()))); _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i))); STADIUMS[i].setStadiaBusy(); } catch (Exception ex) { if (_olympiadInstances.get(i) != null) { for (L2PcInstance player : _olympiadInstances.get(i).getPlayers()) { player.sendMessage("Your olympiad registration was canceled due to an error"); player.setIsInOlympiadMode(false); player.setIsOlympiadStart(false); player.setOlympiadSide(-1); player.setOlympiadGameId(-1); } _olympiadInstances.remove(i); } if (_gamesQueue.get(i) != null) _gamesQueue.remove(i); STADIUMS[i].setStadiaFree(); // try to reuse this stadia next time i--; } } else if (readyClasses != null && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))) { try { _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))); _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i))); STADIUMS[i].setStadiaBusy(); } catch (Exception ex) { if (_olympiadInstances.get(i) != null) { for (L2PcInstance player : _olympiadInstances.get(i).getPlayers()) { player.sendMessage("Your olympiad registration was canceled due to an error"); player.setIsInOlympiadMode(false); player.setIsOlympiadStart(false); player.setOlympiadSide(-1); player.setOlympiadGameId(-1); } _olympiadInstances.remove(i); } if (_gamesQueue.get(i) != null) _gamesQueue.remove(i); STADIUMS[i].setStadiaFree(); // try to reuse this stadia next time i--; } } } else { if (readyClasses != null && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))) { try { _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))); _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i))); STADIUMS[i].setStadiaBusy(); } catch (Exception ex) { if (_olympiadInstances.get(i) != null) { for (L2PcInstance player : _olympiadInstances.get(i).getPlayers()) { player.sendMessage("Your olympiad registration was canceled due to an error"); player.setIsInOlympiadMode(false); player.setIsOlympiadStart(false); player.setOlympiadSide(-1); player.setOlympiadGameId(-1); } _olympiadInstances.remove(i); } if (_gamesQueue.get(i) != null) _gamesQueue.remove(i); STADIUMS[i].setStadiaFree(); // try to reuse this stadia next time i--; } } else if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased())) { try { _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased()))); _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i))); STADIUMS[i].setStadiaBusy(); } catch (Exception ex) { if (_olympiadInstances.get(i) != null) { for (L2PcInstance player : _olympiadInstances.get(i).getPlayers()) { player.sendMessage("Your olympiad registration was canceled due to an error"); player.setIsInOlympiadMode(false); player.setIsOlympiadStart(false); player.setOlympiadSide(-1); player.setOlympiadGameId(-1); } _olympiadInstances.remove(i); } if (_gamesQueue.get(i) != null) _gamesQueue.remove(i); STADIUMS[i].setStadiaFree(); // try to reuse this stadia next time i--; } } } } else { if (_gamesQueue.get(i) == null || _gamesQueue.get(i).isTerminated() || _gamesQueue.get(i)._game == null) { try { _olympiadInstances.remove(i); _gamesQueue.remove(i); STADIUMS[i].setStadiaFree(); i--; } catch (Exception e) { _log.log(Level.WARNING, "Exception on OlympiadManager.run(): " + e.getMessage(), e); } } } } /*try { wait(30000); } catch (InterruptedException e) { }*/ // Start games _gamesQueueSize = _gamesQueue.size(); for (int i = 0; i < _gamesQueueSize; i++) { if (_gamesQueue.get(i) != null && !_gamesQueue.get(i).isTerminated() && !_gamesQueue.get(i).isStarted()) { // start new games Thread T = new Thread(_gamesQueue.get(i)); T.start(); } // Pause one second between games starting to reduce OlympiadManager shout spam. try { wait(1000); } catch (InterruptedException e) { return; } } } // wait 30 sec for !stress the server try { wait(30000); } catch (InterruptedException e) { return; } } // when comp time finish wait for all games terminated before execute // the cleanup code boolean allGamesTerminated = false; // wait for all games terminated while (!allGamesTerminated) { try { wait(30000); } catch (InterruptedException e) { } if (_gamesQueue.isEmpty()) { allGamesTerminated = true; } else { for (OlympiadGameTask game : _gamesQueue.values()) { allGamesTerminated = allGamesTerminated || game.isTerminated(); } } } // when all games terminated clear all _gamesQueue.clear(); _olympiadInstances.clear(); Olympiad.clearRegistered(); OlympiadGame._battleStarted = false; } protected OlympiadGame getOlympiadGame(int index) { if (_olympiadInstances != null && !_olympiadInstances.isEmpty()) { return _olympiadInstances.get(index); } return null; } protected void removeGame(OlympiadGame game) { if (_olympiadInstances != null && !_olympiadInstances.isEmpty()) { for (int i = 0; i < _olympiadInstances.size(); i++) { if (_olympiadInstances.get(i) == game) { _olympiadInstances.remove(i); } } } } protected Map getOlympiadGames() { return (_olympiadInstances == null) ? null : _olympiadInstances; } protected L2FastList getRandomClassList(Map> list, L2FastList classList) { if (list == null || classList == null || list.isEmpty() || classList.isEmpty()) return null; return list.get(classList.get(Rnd.nextInt(classList.size()))); } protected L2FastList nextOpponents(L2FastList list) { L2FastList opponents = new L2FastList(); if (list.isEmpty()) return opponents; int loopCount = (list.size() / 2); int first; int second; if (loopCount < 1) return opponents; first = Rnd.nextInt(list.size()); opponents.add(list.get(first)); list.remove(first); second = Rnd.nextInt(list.size()); opponents.add(list.get(second)); list.remove(second); return opponents; } protected boolean existNextOpponents(L2FastList list) { if (list == null) return false; if (list.isEmpty()) return false; int loopCount = list.size() >> 1; if (loopCount < 1) return false; else return true; } protected FastMap getAllTitles() { FastMap titles = new FastMap(); for (OlympiadGame instance : _olympiadInstances.values()) { if (instance._gamestarted != true) continue; titles.put(instance._stadiumID, instance.getTitle()); } return titles; } @SuppressWarnings("synthetic-access") private static class SingletonHolder { protected static final OlympiadManager _instance = new OlympiadManager(); } }