OlympiadManager.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.l2jserver.gameserver.model.olympiad;
  16. import java.util.Map;
  17. import java.util.logging.Level;
  18. import java.util.logging.Logger;
  19. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  20. import com.l2jserver.gameserver.model.olympiad.Olympiad.COMP_TYPE;
  21. import com.l2jserver.util.L2FastList;
  22. import com.l2jserver.util.Rnd;
  23. import javolution.util.FastMap;
  24. /**
  25. *
  26. * @author GodKratos
  27. */
  28. class OlympiadManager implements Runnable
  29. {
  30. protected static final Logger _log = Logger.getLogger(OlympiadManager.class.getName());
  31. private Map<Integer, OlympiadGame> _olympiadInstances;
  32. protected static final OlympiadStadium[] STADIUMS = {
  33. new OlympiadStadium(-88000, -252637, -3331, 17100001, 17100002),
  34. new OlympiadStadium(-83760, -252637, -3331, 17100003, 17100004),
  35. new OlympiadStadium(-79600, -252637, -3331, 17100005, 17100006),
  36. new OlympiadStadium(-75648, -252637, -3331, 17100007, 17100008),
  37. new OlympiadStadium(-88000, -249762, -3331, 17100009, 17100010),
  38. new OlympiadStadium(-83760, -249762, -3331, 17100011, 17100012),
  39. new OlympiadStadium(-79600, -249762, -3331, 17100013, 17100014),
  40. new OlympiadStadium(-75648, -249762, -3331, 17100015, 17100016),
  41. new OlympiadStadium(-88000, -246951, -3331, 17100017, 17100018),
  42. new OlympiadStadium(-83760, -246951, -3331, 17100019, 17100020),
  43. new OlympiadStadium(-79600, -246951, -3331, 17100021, 17100022),
  44. new OlympiadStadium(-75648, -246951, -3331, 17100023, 17100024),
  45. new OlympiadStadium(-88000, -244290, -3331, 17100025, 17100026),
  46. new OlympiadStadium(-83760, -244290, -3331, 17100027, 17100028),
  47. new OlympiadStadium(-79600, -244290, -3331, 17100029, 17100030),
  48. new OlympiadStadium(-75648, -244290, -3331, 17100031, 17100032),
  49. new OlympiadStadium(-88000, -241490, -3331, 17100033, 17100034),
  50. new OlympiadStadium(-83760, -241490, -3331, 17100035, 17100036),
  51. new OlympiadStadium(-79600, -241490, -3331, 17100037, 17100038),
  52. new OlympiadStadium(-75648, -241490, -3331, 17100039, 17100040),
  53. new OlympiadStadium(-88000, -238825, -3331, 17100041, 17100042),
  54. new OlympiadStadium(-83760, -238825, -3331, 17100043, 17100044)
  55. };
  56. private OlympiadManager()
  57. {
  58. _olympiadInstances = new FastMap<Integer, OlympiadGame>();
  59. }
  60. public static OlympiadManager getInstance()
  61. {
  62. return SingletonHolder._instance;
  63. }
  64. public synchronized void run()
  65. {
  66. if (Olympiad.getInstance().isOlympiadEnd())
  67. return;
  68. Map<Integer, OlympiadGameTask> _gamesQueue = new FastMap<Integer, OlympiadGameTask>();
  69. while (Olympiad.getInstance().inCompPeriod())
  70. {
  71. if (Olympiad.getNobleCount() == 0)
  72. {
  73. try
  74. {
  75. wait(60000);
  76. }
  77. catch (InterruptedException ex)
  78. {
  79. return;
  80. }
  81. continue;
  82. }
  83. int _gamesQueueSize = 0;
  84. // _compStarted = true;
  85. L2FastList<Integer> readyClasses = Olympiad.hasEnoughRegisteredClassed();
  86. boolean readyNonClassed = Olympiad.hasEnoughRegisteredNonClassed();
  87. if (readyClasses != null || readyNonClassed)
  88. {
  89. // set up the games queue
  90. for (int i = 0; i < STADIUMS.length; i++)
  91. {
  92. if (!existNextOpponents(Olympiad.getRegisteredNonClassBased())
  93. && !existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
  94. {
  95. break;
  96. }
  97. if (STADIUMS[i].isFreeToUse())
  98. {
  99. if (i < STADIUMS.length / 2)
  100. {
  101. if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased()))
  102. {
  103. try
  104. {
  105. _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased())));
  106. _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
  107. STADIUMS[i].setStadiaBusy();
  108. }
  109. catch (Exception ex)
  110. {
  111. if (_olympiadInstances.get(i) != null)
  112. {
  113. for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
  114. {
  115. player.sendMessage("Your olympiad registration was canceled due to an error");
  116. player.setIsInOlympiadMode(false);
  117. player.setIsOlympiadStart(false);
  118. player.setOlympiadSide(-1);
  119. player.setOlympiadGameId(-1);
  120. }
  121. _olympiadInstances.remove(i);
  122. }
  123. if (_gamesQueue.get(i) != null)
  124. _gamesQueue.remove(i);
  125. STADIUMS[i].setStadiaFree();
  126. // try to reuse this stadia next time
  127. i--;
  128. }
  129. }
  130. else if (readyClasses != null
  131. && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
  132. {
  133. try
  134. {
  135. _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))));
  136. _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
  137. STADIUMS[i].setStadiaBusy();
  138. }
  139. catch (Exception ex)
  140. {
  141. if (_olympiadInstances.get(i) != null)
  142. {
  143. for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
  144. {
  145. player.sendMessage("Your olympiad registration was canceled due to an error");
  146. player.setIsInOlympiadMode(false);
  147. player.setIsOlympiadStart(false);
  148. player.setOlympiadSide(-1);
  149. player.setOlympiadGameId(-1);
  150. }
  151. _olympiadInstances.remove(i);
  152. }
  153. if (_gamesQueue.get(i) != null)
  154. _gamesQueue.remove(i);
  155. STADIUMS[i].setStadiaFree();
  156. // try to reuse this stadia next time
  157. i--;
  158. }
  159. }
  160. }
  161. else
  162. {
  163. if (readyClasses != null
  164. && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
  165. {
  166. try
  167. {
  168. _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))));
  169. _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
  170. STADIUMS[i].setStadiaBusy();
  171. }
  172. catch (Exception ex)
  173. {
  174. if (_olympiadInstances.get(i) != null)
  175. {
  176. for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
  177. {
  178. player.sendMessage("Your olympiad registration was canceled due to an error");
  179. player.setIsInOlympiadMode(false);
  180. player.setIsOlympiadStart(false);
  181. player.setOlympiadSide(-1);
  182. player.setOlympiadGameId(-1);
  183. }
  184. _olympiadInstances.remove(i);
  185. }
  186. if (_gamesQueue.get(i) != null)
  187. _gamesQueue.remove(i);
  188. STADIUMS[i].setStadiaFree();
  189. // try to reuse this stadia next time
  190. i--;
  191. }
  192. }
  193. else if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased()))
  194. {
  195. try
  196. {
  197. _olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased())));
  198. _gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
  199. STADIUMS[i].setStadiaBusy();
  200. }
  201. catch (Exception ex)
  202. {
  203. if (_olympiadInstances.get(i) != null)
  204. {
  205. for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
  206. {
  207. player.sendMessage("Your olympiad registration was canceled due to an error");
  208. player.setIsInOlympiadMode(false);
  209. player.setIsOlympiadStart(false);
  210. player.setOlympiadSide(-1);
  211. player.setOlympiadGameId(-1);
  212. }
  213. _olympiadInstances.remove(i);
  214. }
  215. if (_gamesQueue.get(i) != null)
  216. _gamesQueue.remove(i);
  217. STADIUMS[i].setStadiaFree();
  218. // try to reuse this stadia next time
  219. i--;
  220. }
  221. }
  222. }
  223. }
  224. else
  225. {
  226. if (_gamesQueue.get(i) == null || _gamesQueue.get(i).isTerminated() || _gamesQueue.get(i)._game == null)
  227. {
  228. try
  229. {
  230. _olympiadInstances.remove(i);
  231. _gamesQueue.remove(i);
  232. STADIUMS[i].setStadiaFree();
  233. i--;
  234. }
  235. catch (Exception e)
  236. {
  237. _log.log(Level.WARNING, "Exception on OlympiadManager.run(): " + e.getMessage(), e);
  238. }
  239. }
  240. }
  241. }
  242. /*try
  243. {
  244. wait(30000);
  245. }
  246. catch (InterruptedException e)
  247. {
  248. }*/
  249. // Start games
  250. _gamesQueueSize = _gamesQueue.size();
  251. for (int i = 0; i < _gamesQueueSize; i++)
  252. {
  253. if (_gamesQueue.get(i) != null && !_gamesQueue.get(i).isTerminated() && !_gamesQueue.get(i).isStarted())
  254. {
  255. // start new games
  256. Thread T = new Thread(_gamesQueue.get(i));
  257. T.start();
  258. }
  259. // Pause one second between games starting to reduce OlympiadManager shout spam.
  260. try
  261. {
  262. wait(1000);
  263. }
  264. catch (InterruptedException e)
  265. {
  266. return;
  267. }
  268. }
  269. }
  270. // wait 30 sec for !stress the server
  271. try
  272. {
  273. wait(30000);
  274. }
  275. catch (InterruptedException e)
  276. {
  277. return;
  278. }
  279. }
  280. // when comp time finish wait for all games terminated before execute
  281. // the cleanup code
  282. boolean allGamesTerminated = false;
  283. // wait for all games terminated
  284. while (!allGamesTerminated)
  285. {
  286. try
  287. {
  288. wait(30000);
  289. }
  290. catch (InterruptedException e)
  291. {
  292. }
  293. if (_gamesQueue.isEmpty())
  294. {
  295. allGamesTerminated = true;
  296. }
  297. else
  298. {
  299. for (OlympiadGameTask game : _gamesQueue.values())
  300. {
  301. allGamesTerminated = allGamesTerminated || game.isTerminated();
  302. }
  303. }
  304. }
  305. // when all games terminated clear all
  306. _gamesQueue.clear();
  307. _olympiadInstances.clear();
  308. Olympiad.clearRegistered();
  309. OlympiadGame._battleStarted = false;
  310. }
  311. protected OlympiadGame getOlympiadGame(int index)
  312. {
  313. if (_olympiadInstances != null && !_olympiadInstances.isEmpty())
  314. {
  315. return _olympiadInstances.get(index);
  316. }
  317. return null;
  318. }
  319. protected void removeGame(OlympiadGame game)
  320. {
  321. if (_olympiadInstances != null && !_olympiadInstances.isEmpty())
  322. {
  323. for (int i = 0; i < _olympiadInstances.size(); i++)
  324. {
  325. if (_olympiadInstances.get(i) == game)
  326. {
  327. _olympiadInstances.remove(i);
  328. }
  329. }
  330. }
  331. }
  332. protected Map<Integer, OlympiadGame> getOlympiadGames()
  333. {
  334. return (_olympiadInstances == null) ? null : _olympiadInstances;
  335. }
  336. protected L2FastList<L2PcInstance> getRandomClassList(Map<Integer, L2FastList<L2PcInstance>> list, L2FastList<Integer> classList)
  337. {
  338. if (list == null || classList == null || list.isEmpty() || classList.isEmpty())
  339. return null;
  340. return list.get(classList.get(Rnd.nextInt(classList.size())));
  341. }
  342. protected L2FastList<L2PcInstance> nextOpponents(L2FastList<L2PcInstance> list)
  343. {
  344. L2FastList<L2PcInstance> opponents = new L2FastList<L2PcInstance>();
  345. if (list.isEmpty())
  346. return opponents;
  347. int loopCount = (list.size() / 2);
  348. int first;
  349. int second;
  350. if (loopCount < 1)
  351. return opponents;
  352. first = Rnd.nextInt(list.size());
  353. opponents.add(list.get(first));
  354. list.remove(first);
  355. second = Rnd.nextInt(list.size());
  356. opponents.add(list.get(second));
  357. list.remove(second);
  358. return opponents;
  359. }
  360. protected boolean existNextOpponents(L2FastList<L2PcInstance> list)
  361. {
  362. if (list == null)
  363. return false;
  364. if (list.isEmpty())
  365. return false;
  366. int loopCount = list.size() >> 1;
  367. if (loopCount < 1)
  368. return false;
  369. else
  370. return true;
  371. }
  372. protected FastMap<Integer, String> getAllTitles()
  373. {
  374. FastMap<Integer, String> titles = new FastMap<Integer, String>();
  375. for (OlympiadGame instance : _olympiadInstances.values())
  376. {
  377. if (instance._gamestarted != true)
  378. continue;
  379. titles.put(instance._stadiumID, instance.getTitle());
  380. }
  381. return titles;
  382. }
  383. @SuppressWarnings("synthetic-access")
  384. private static class SingletonHolder
  385. {
  386. protected static final OlympiadManager _instance = new OlympiadManager();
  387. }
  388. }