WorldRegistryImpl.java
上传用户:gwt600
上传日期:2021-06-03
资源大小:704k
文件大小:19k
源码类别:

游戏

开发平台:

Java

  1. /*
  2. This file is part of the OdinMS Maple Story Server
  3. Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc> 
  4. Matthias Butz <matze@odinms.de>
  5. Jan Christian Meyer <vimes@odinms.de>
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Affero General Public License version 3
  8. as published by the Free Software Foundation. You may not use, modify
  9. or distribute this program under any other version of the
  10. GNU Affero General Public License.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU Affero General Public License for more details.
  15. You should have received a copy of the GNU Affero General Public License
  16. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18. /*
  19.  * To change this template, choose Tools | Templates and open the template in the editor.
  20.  */
  21. package net.sf.odinms.net.world;
  22. import java.rmi.ConnectException;
  23. import java.rmi.RemoteException;
  24. import java.rmi.server.UnicastRemoteObject;
  25. import java.sql.Connection;
  26. import java.sql.PreparedStatement;
  27. import java.sql.ResultSet;
  28. import java.sql.SQLException;
  29. import java.util.ArrayList;
  30. import java.util.Collection;
  31. import java.util.Collections;
  32. import java.util.Comparator;
  33. import java.util.HashMap;
  34. import java.util.HashSet;
  35. import java.util.LinkedHashMap;
  36. import java.util.LinkedList;
  37. import java.util.List;
  38. import java.util.Map;
  39. import java.util.Map.Entry;
  40. import java.util.Properties;
  41. import java.util.Set;
  42. import java.util.concurrent.atomic.AtomicInteger;
  43. import javax.rmi.ssl.SslRMIClientSocketFactory;
  44. import javax.rmi.ssl.SslRMIServerSocketFactory;
  45. import net.sf.odinms.database.DatabaseConnection;
  46. import net.sf.odinms.net.MaplePacket;
  47. import net.sf.odinms.net.channel.remote.ChannelWorldInterface;
  48. import net.sf.odinms.net.login.remote.LoginWorldInterface;
  49. import net.sf.odinms.net.world.guild.MapleAlliance;
  50. import net.sf.odinms.net.world.guild.MapleGuild;
  51. import net.sf.odinms.net.world.guild.MapleGuildCharacter;
  52. import net.sf.odinms.net.world.remote.WorldChannelInterface;
  53. import net.sf.odinms.net.world.remote.WorldLoginInterface;
  54. import net.sf.odinms.net.world.remote.WorldRegistry;
  55. import org.slf4j.Logger;
  56. import org.slf4j.LoggerFactory;
  57. /**
  58.  * 
  59.  * @author Matze
  60.  */
  61. public class WorldRegistryImpl extends UnicastRemoteObject implements WorldRegistry {
  62.     private static final long serialVersionUID = -5170574938159280746L;
  63.     private static WorldRegistryImpl instance = null;
  64.     private static Logger log = LoggerFactory.getLogger(WorldRegistryImpl.class);
  65.     private Map<Integer, ChannelWorldInterface> channelServer = new LinkedHashMap<Integer, ChannelWorldInterface>();
  66.     private List<LoginWorldInterface> loginServer = new LinkedList<LoginWorldInterface>();
  67.     private Map<Integer, MapleParty> parties = new HashMap<Integer, MapleParty>();
  68.     private AtomicInteger runningPartyId = new AtomicInteger();
  69.     private Map<Integer, MapleMessenger> messengers = new HashMap<Integer, MapleMessenger>();
  70.     private AtomicInteger runningMessengerId = new AtomicInteger();
  71.     private Map<Integer, MapleGuild> guilds = new LinkedHashMap<Integer, MapleGuild>();
  72.     private PlayerBuffStorage buffStorage = new PlayerBuffStorage();
  73.     private Map<Integer, MapleAlliance> alliances = new LinkedHashMap<Integer, MapleAlliance>(); // contains id and alliance info.
  74.     private WorldRegistryImpl() throws RemoteException {
  75.         super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
  76.         DatabaseConnection.setProps(WorldServer.getInstance().getDbProp());
  77.         Connection con = DatabaseConnection.getConnection();
  78.         PreparedStatement ps;
  79.         try {
  80.             ps = con.prepareStatement("SELECT MAX(party)+1 FROM characters");
  81.             ResultSet rs = ps.executeQuery();
  82.             rs.next();
  83.             runningPartyId.set(rs.getInt(1));
  84.             rs.close();
  85.             ps.close();
  86.         } catch (SQLException e) {
  87.             // TODO Auto-generated catch block
  88.             e.printStackTrace();
  89.         }
  90.         runningMessengerId.set(1);
  91.     }
  92.     public static WorldRegistryImpl getInstance() {
  93.         if (instance == null) {
  94.             try {
  95.                 instance = new WorldRegistryImpl();
  96.             } catch (RemoteException e) {
  97.                 // can't do much anyway we are fucked ^^
  98.                 throw new RuntimeException(e);
  99.             }
  100.         }
  101.         return instance;
  102.     }
  103.     private int getFreeChannelId() {
  104.         for (int i = 0; i < 30; i++) {
  105.             if (!channelServer.containsKey(i)) {
  106.                 return i;
  107.             }
  108.         }
  109.         return -1;
  110.     }
  111.     public WorldChannelInterface registerChannelServer(String authKey, ChannelWorldInterface cb) throws RemoteException {
  112.         try {
  113.             Connection con = DatabaseConnection.getConnection();
  114.             PreparedStatement ps = con.prepareStatement("SELECT * FROM channels WHERE `key` = SHA1(?) AND world = ?");
  115.             ps.setString(1, authKey);
  116.             ps.setInt(2, WorldServer.getInstance().getWorldId());
  117.             ResultSet rs = ps.executeQuery();
  118.             if (rs.next()) {
  119.                 int channelId = rs.getInt("number");
  120.                 if (channelId < 1) {
  121.                     channelId = getFreeChannelId();
  122.                     if (channelId == -1) {
  123.                         throw new RuntimeException("Maximum channels reached");
  124.                     }
  125.                 } else {
  126.                     if (channelServer.containsKey(channelId)) {
  127.                         ChannelWorldInterface oldch = channelServer.get(channelId);
  128.                         try {
  129.                             oldch.shutdown(0);
  130.                         } catch (ConnectException ce) {
  131.                             // silently ignore as we assume that the server is offline
  132.                         }
  133.                     // int switchChannel = getFreeChannelId();
  134.                     // if (switchChannel == -1) {
  135.                     // throw new RuntimeException("Maximum channels reached");
  136.                     // }
  137.                     // ChannelWorldInterface switchIf = channelServer.get(channelId);
  138.                     // deregisterChannelServer(switchChannel);
  139.                     // channelServer.put(switchChannel, switchIf);
  140.                     // switchIf.setChannelId(switchChannel);
  141.                     // for (LoginWorldInterface wli : loginServer) {
  142.                     // wli.channelOnline(switchChannel, switchIf.getIP());
  143.                     // }
  144.                     }
  145.                 }
  146.                 channelServer.put(channelId, cb);
  147.                 cb.setChannelId(channelId);
  148.                 WorldChannelInterface ret = new WorldChannelInterfaceImpl(cb, rs.getInt("channelid"));
  149.                 rs.close();
  150.                 ps.close();
  151.                 return ret;
  152.             }
  153.             rs.close();
  154.             ps.close();
  155.         } catch (SQLException ex) {
  156.             log.error("Encountered database error while authenticating channelserver", ex);
  157.         }
  158.         throw new RuntimeException("Couldn't find a channel with the given key (" + authKey + ")");
  159.     }
  160.     public void deregisterChannelServer(int channel) throws RemoteException {
  161.         channelServer.remove(channel);
  162.         for (LoginWorldInterface wli : loginServer) {
  163.             wli.channelOffline(channel);
  164.         }
  165.         log.info("Channel {} is offline.", channel);
  166.     }
  167.     public WorldLoginInterface registerLoginServer(String authKey, LoginWorldInterface cb) throws RemoteException {
  168.         WorldLoginInterface ret = null;
  169.         try {
  170.             Connection con = DatabaseConnection.getConnection();
  171.             PreparedStatement ps = con.prepareStatement("SELECT * FROM loginserver WHERE `key` = SHA1(?) AND world = ?");
  172.             ps.setString(1, authKey);
  173.             ps.setInt(2, WorldServer.getInstance().getWorldId());
  174.             ResultSet rs = ps.executeQuery();
  175.             if (rs.next()) {
  176.                 loginServer.add(cb);
  177.                 for (ChannelWorldInterface cwi : channelServer.values()) {
  178.                     cb.channelOnline(cwi.getChannelId(), authKey);
  179.                 }
  180.             }
  181.             rs.close();
  182.             ps.close();
  183.             ret = new WorldLoginInterfaceImpl();
  184.         } catch (Exception e) {
  185.             log.error("Encountered database error while authenticating loginserver", e);
  186.         }
  187.         return ret;
  188.     }
  189.     public void deregisterLoginServer(LoginWorldInterface cb) throws RemoteException {
  190.         loginServer.remove(cb);
  191.     }
  192.     public List<LoginWorldInterface> getLoginServer() {
  193.         return new LinkedList<LoginWorldInterface>(loginServer);
  194.     }
  195.     public ChannelWorldInterface getChannel(int channel) {
  196.         return channelServer.get(channel);
  197.     }
  198.     public Set<Integer> getChannelServer() {
  199.         return new HashSet<Integer>(channelServer.keySet());
  200.     }
  201.     public Collection<ChannelWorldInterface> getAllChannelServers() {
  202.         return channelServer.values();
  203.     }
  204.     public int getHighestChannelId() {
  205.         int highest = 0;
  206.         for (Integer channel : channelServer.keySet()) {
  207.             if (channel != null && channel.intValue() > highest) {
  208.                 highest = channel.intValue();
  209.             }
  210.         }
  211.         return highest;
  212.     }
  213.     public MapleParty createParty(MaplePartyCharacter chrfor) {
  214.         int partyid = runningPartyId.getAndIncrement();
  215.         MapleParty party = new MapleParty(partyid, chrfor);
  216.         parties.put(partyid, party);
  217.         return party;
  218.     }
  219.     public MapleParty getParty(int partyid) {
  220.         return parties.get(partyid);
  221.     }
  222.     public MapleParty disbandParty(int partyid) {
  223.         return parties.remove(partyid);
  224.     }
  225.     public String getStatus() throws RemoteException {
  226.         StringBuilder ret = new StringBuilder();
  227.         List<Entry<Integer, ChannelWorldInterface>> channelServers = new ArrayList<Entry<Integer, ChannelWorldInterface>>(channelServer.entrySet());
  228.         Collections.sort(channelServers, new Comparator<Entry<Integer, ChannelWorldInterface>>() {
  229.             @Override
  230.             public int compare(Entry<Integer, ChannelWorldInterface> o1, Entry<Integer, ChannelWorldInterface> o2) {
  231.                 return o1.getKey().compareTo(o2.getKey());
  232.             }
  233.         });
  234.         int totalUsers = 0;
  235.         for (Entry<Integer, ChannelWorldInterface> cs : channelServers) {
  236.             ret.append("Channel ");
  237.             ret.append(cs.getKey());
  238.             try {
  239.                 cs.getValue().isAvailable();
  240.                 ret.append(": online, ");
  241.                 int channelUsers = cs.getValue().getConnected();
  242.                 totalUsers += channelUsers;
  243.                 ret.append(channelUsers);
  244.                 ret.append(" usersn");
  245.             } catch (RemoteException e) {
  246.                 ret.append(": offlinen");
  247.             }
  248.         }
  249.         ret.append("Total users online: ");
  250.         ret.append(totalUsers);
  251.         ret.append("n");
  252.         Properties props = new Properties(WorldServer.getInstance().getWorldProp());
  253.         int loginInterval = Integer.parseInt(props.getProperty("net.sf.odinms.login.interval"));
  254.         for (LoginWorldInterface lwi : loginServer) {
  255.             ret.append("Login: ");
  256.             try {
  257.                 lwi.isAvailable();
  258.                 ret.append("onlinen");
  259.                 ret.append("Users waiting in login queue: ");
  260.                 ret.append(lwi.getWaitingUsers());
  261.                 ret.append(" usersn");
  262.                 int loginMinutes = (int) Math.ceil((double) loginInterval * ((double) lwi.getWaitingUsers() / lwi.getPossibleLoginAverage())) / 60000;
  263.                 ret.append("Current average login waiting time: ");
  264.                 ret.append(loginMinutes);
  265.                 ret.append(" minutesn");
  266.             } catch (RemoteException e) {
  267.                 ret.append("offlinen");
  268.             }
  269.         }
  270.         return ret.toString();
  271.     }
  272.     public int createGuild(int leaderId, String name) {
  273.         return MapleGuild.createGuild(leaderId, name);
  274.     }
  275.     public MapleGuild getGuild(int id, MapleGuildCharacter mgc) {
  276.         synchronized (guilds) {
  277.             if (guilds.get(id) != null) {
  278.                 return guilds.get(id);
  279.             }
  280.             MapleGuild g = new MapleGuild(id, mgc);
  281.             if (g.getId() == -1) {//failed to load
  282.                 return null;
  283.             }
  284.             guilds.put(id, g);
  285.             return g;
  286.         }
  287.     }
  288.     public void clearGuilds() //force a reload of guilds from db
  289.     {
  290.         synchronized (guilds) {
  291.             guilds.clear();
  292.         }
  293.         //reload all the online characters in guilds
  294.         try {
  295.             for (ChannelWorldInterface cwi : this.getAllChannelServers()) {
  296.                 cwi.reloadGuildCharacters();
  297.             }
  298.         } catch (RemoteException re) {
  299.             log.error("RemoteException occurred while attempting to reload guilds.", re);
  300.         }
  301.     }
  302.     public void setGuildMemberOnline(MapleGuildCharacter mgc, boolean bOnline, int channel) {
  303.         MapleGuild g = getGuild(mgc.getGuildId(), mgc);
  304.         g.setOnline(mgc.getId(), bOnline, channel);
  305.     }
  306.     public int addGuildMember(MapleGuildCharacter mgc) {
  307.         MapleGuild g = guilds.get(mgc.getGuildId());
  308.         if (g != null) {
  309.             return g.addGuildMember(mgc);
  310.         }
  311.         return 0;
  312.     }
  313.     public void leaveGuild(MapleGuildCharacter mgc) {
  314.         MapleGuild g = guilds.get(mgc.getGuildId());
  315.         if (g != null) {
  316.             g.leaveGuild(mgc);
  317.         }
  318.     }
  319.     public void guildChat(int gid, String name, int cid, String msg) {
  320.         MapleGuild g = guilds.get(gid);
  321.         if (g != null) {
  322.             g.guildChat(name, cid, msg);
  323.         }
  324.     }
  325.     public void changeRank(int gid, int cid, int newRank) {
  326.         MapleGuild g = guilds.get(gid);
  327.         if (g != null) {
  328.             g.changeRank(cid, newRank);
  329.         }
  330.     }
  331.     public void expelMember(MapleGuildCharacter initiator, String name, int cid) {
  332.         MapleGuild g = guilds.get(initiator.getGuildId());
  333.         if (g != null) {
  334.             g.expelMember(initiator, name, cid);
  335.         }
  336.     }
  337.     public void setGuildNotice(int gid, String notice) {
  338.         MapleGuild g = guilds.get(gid);
  339.         if (g != null) {
  340.             g.setGuildNotice(notice);
  341.         }
  342.     }
  343.     public void memberLevelJobUpdate(MapleGuildCharacter mgc) {
  344.         MapleGuild g = guilds.get(mgc.getGuildId());
  345.         if (g != null) {
  346.             g.memberLevelJobUpdate(mgc);
  347.         }
  348.     }
  349.     public void changeRankTitle(int gid, String[] ranks) {
  350.         MapleGuild g = guilds.get(gid);
  351.         if (g != null) {
  352.             g.changeRankTitle(ranks);
  353.         }
  354.     }
  355.     public void setGuildEmblem(int gid, short bg, byte bgcolor, short logo, byte logocolor) {
  356.         MapleGuild g = guilds.get(gid);
  357.         if (g != null) {
  358.             g.setGuildEmblem(bg, bgcolor, logo, logocolor);
  359.         }
  360.     }
  361.     public void disbandGuild(int gid) {
  362.         synchronized (guilds) {
  363.             MapleGuild g = guilds.get(gid);
  364.             g.disbandGuild();
  365.             guilds.remove(gid);
  366.         }
  367.     }
  368.     public boolean setGuildAllianceId(int gId, int aId) {
  369.         MapleGuild guild = guilds.get(gId);
  370.         if (guild != null) {
  371.             guild.setAllianceId(aId);
  372.             return true;
  373.         }
  374.         return false;
  375.     }
  376.     public boolean increaseGuildCapacity(int gid) {
  377.         MapleGuild g = guilds.get(gid);
  378.         if (g != null) {
  379.             return g.increaseCapacity();
  380.         }
  381.         return false;
  382.     }
  383.     public void gainGP(int gid, int amount) {
  384.         MapleGuild g = guilds.get(gid);
  385.         if (g != null) {
  386.             g.gainGP(amount);
  387.         }
  388.     }
  389.     public MapleMessenger createMessenger(MapleMessengerCharacter chrfor) {
  390.         int messengerid = runningMessengerId.getAndIncrement();
  391.         MapleMessenger messenger = new MapleMessenger(messengerid, chrfor);
  392.         messengers.put(messenger.getId(), messenger);
  393.         return messenger;
  394.     }
  395.     public MapleMessenger getMessenger(int messengerid) {
  396.         return messengers.get(messengerid);
  397.     }
  398.     public PlayerBuffStorage getPlayerBuffStorage() {
  399.         return buffStorage;
  400.     }
  401.     public MapleAlliance getAlliance(int id) {
  402.         synchronized (alliances) {
  403.             if (alliances.containsKey(id)) {
  404.                 return alliances.get(id);
  405.             }
  406.             return null;
  407.         }
  408.     }
  409.     public void addAlliance(int id, MapleAlliance alliance) {
  410.         synchronized (alliances) {
  411.             if (!alliances.containsKey(id)) {
  412.                 alliances.put(id, alliance);
  413.             }
  414.         }
  415.     }
  416.     public void disbandAlliance(int id) {
  417.         synchronized (alliances) {
  418.             MapleAlliance alliance = alliances.get(id);
  419.             if (alliance != null) {
  420.                 for (Integer gid : alliance.getGuilds()) {
  421.                         MapleGuild guild = guilds.get(gid);
  422.                         guild.setAllianceId(0);
  423.                 }
  424.                 alliances.remove(id);
  425.             }
  426.         }
  427.     }
  428.     public void allianceMessage(int id, MaplePacket packet, int exception, int guildex) {
  429.         MapleAlliance alliance = alliances.get(id);
  430.         if (alliance != null) {
  431.             for (Integer gid : alliance.getGuilds()) {
  432.                 if (guildex == gid) {
  433.                     continue;
  434.                 }
  435.                 MapleGuild guild = guilds.get(gid);
  436.                 if (guild != null) {
  437.                     guild.broadcast(packet, exception);
  438.                 }
  439.             }
  440.         }
  441.     }
  442.     public boolean addGuildtoAlliance(int aId, int guildId) {
  443.         MapleAlliance alliance = alliances.get(aId);
  444.         if (alliance != null) {
  445.             alliance.addGuild(guildId);
  446.             return true;
  447.         }
  448.         return false;
  449.     }
  450.     public boolean removeGuildFromAlliance(int aId, int guildId) {
  451.         MapleAlliance alliance = alliances.get(aId);
  452.         if (alliance != null) {
  453.             alliance.removeGuild(guildId);
  454.             return true;
  455.         }
  456.         return false;
  457.     }
  458.     public boolean setAllianceRanks(int aId, String[] ranks) {
  459.         MapleAlliance alliance = alliances.get(aId);
  460.         if (alliance != null) {
  461.             alliance.setRankTitle(ranks);
  462.             return true;
  463.         }
  464.         return false;
  465.     }
  466.     public boolean setAllianceNotice(int aId, String notice) {
  467.         MapleAlliance alliance = alliances.get(aId);
  468.         if (alliance != null) {
  469.             alliance.setNotice(notice);
  470.             return true;
  471.         }
  472.         return false;
  473.     }
  474.     public boolean increaseAllianceCapacity(int aId, int inc) {
  475.         MapleAlliance alliance = alliances.get(aId);
  476.         if (alliance != null) {
  477.             alliance.increaseCapacity(inc);
  478.             return true;
  479.         }
  480.         return false;
  481.     }
  482. }