Package org.pokenet.server.network

Source Code of org.pokenet.server.network.LogoutManager

package org.pokenet.server.network;

import java.sql.ResultSet;
import java.util.LinkedList;
import java.util.Queue;

import org.pokenet.server.GameServer;
import org.pokenet.server.backend.entity.Bag;
import org.pokenet.server.backend.entity.PlayerChar;
import org.pokenet.server.battle.DataService;
import org.pokenet.server.battle.Pokemon;
import org.pokenet.server.battle.PokemonSpecies;
import org.pokenet.server.battle.mechanics.statuses.abilities.IntrinsicAbility;

/**
* Handles logging players out
* @author shadowkanji
*
*/
public class LogoutManager implements Runnable {
  private Queue<PlayerChar> m_logoutQueue;
  private Thread m_thread;
  private boolean m_isRunning;
  private MySqlManager m_database;
 
  /**
   * Default constructor
   */
  public LogoutManager() {
    m_database = new MySqlManager();
    m_logoutQueue = new LinkedList<PlayerChar>();
    m_thread = null;
  }
 
  /**
   * Returns how many players are in the save queue
   * @return
   */
  public int getPlayerAmount() {
    return m_logoutQueue.size();
  }
 
  /**
   * Attempts to logout a player by saving their data. Returns true on success
   * @param player
   */
  private boolean attemptLogout(PlayerChar player) {
    //Remove player from their map if it hasn't been done already
    if(player.getMap() != null)
      player.getMap().removeChar(player);
    TcpProtocolHandler.removePlayer(player);
    UdpProtocolHandler.removePlayer(player);
    GameServer.getInstance().updatePlayerCount();
    m_database = new MySqlManager();
    if(!m_database.connect(GameServer.getDatabaseHost(), GameServer.getDatabaseUsername(), GameServer.getDatabasePassword()))
      return false;
    m_database.selectDatabase(GameServer.getDatabaseName());
    //Store all player information
    if(!savePlayer(player)) {
      m_database.close();
      return false;
    }
    //Finally, store that the player is logged out and close connection
    m_database.query("UPDATE pn_members SET lastLoginServer='null' WHERE id='" + player.getId() + "'");
    m_database.close();
    GameServer.getServiceManager().getMovementService().removePlayer(player.getName());
    return true;
  }
 
  /**
   * Queues a player to be logged out
   * @param player
   */
  public void queuePlayer(PlayerChar player) {
    if(m_thread == null || !m_thread.isAlive())
      start();
    if(!m_logoutQueue.contains(player))
      m_logoutQueue.offer(player);
  }

  /**
   * Called by m_thread.start()
   */
  public void run() {
    while(m_isRunning) {
      synchronized(m_logoutQueue) {
        if(m_logoutQueue.peek() != null) {
          PlayerChar p = m_logoutQueue.poll();
          synchronized(p) {
            if(p != null) {
              if(!attemptLogout(p)) {
                m_logoutQueue.add(p);
              } else {
                p.dispose();
                System.out.println("INFO: " + p.getName() + " logged out.");
                p = null;
              }
            }
          }
        }
      }
      try {
        Thread.sleep(500);
      } catch (Exception e) {}
    }
    m_thread = null;
    System.out.println("INFO: All player data saved successfully.");
  }
 
  /**
   * Start this logout manager
   */
  public void start() {
    if(m_thread == null || !m_thread.isAlive()) {
      m_thread = new Thread(this);
      m_isRunning = true;
      m_thread.start();
    }
  }
 
  /**
   * Stop this logout manager
   */
  public void stop() {
    //Stop the thread
    m_isRunning = false;
  }
 
  /**
   * Saves a player object to the database (Updates an existing player)
   * @param p
   * @return
   */
  private boolean savePlayer(PlayerChar p) {
    try {
      /*
       * First, check if they have logged in somewhere else.
       * This is useful for when as server loses its internet connection
       */
      ResultSet data = m_database.query("SELECT * FROM pn_members WHERE id='" + p.getId() "'");
      data.first();
      if(data.getLong("lastLoginTime") == p.getLastLoginTime()) {
        /* Check they are not trading */
        if(p.isTrading()) {
          /* If the trade is still executing, don't save them yet */
          if(!p.getTrade().endTrade())
            return false;
        }
        /*
         * Update the player row
         */
        String badges = "";
        for(int i = 0; i < 42; i++) {
          if(p.getBadges()[i] == 1)
            badges = badges + "1";
          else
            badges = badges + "0";
        }
        m_database.query("UPDATE pn_members SET " +
            "muted='" + p.isMuted() + "', " +
            "sprite='" + p.getRawSprite() + "', " +
            "money='" + p.getMoney() + "', " +
            "skHerb='" + p.getHerbalismExp() + "', " +
            "skCraft='" + p.getCraftingExp() + "', " +
            "skFish='" + p.getFishingExp() + "', " +
            "skTrain='" + p.getTrainingExp() + "', " +
            "skCoord='" + p.getCoordinatingExp() + "', " +
            "skBreed='" + p.getBreedingExp() + "', " +
            "x='" + p.getX() + "', " +
            "y='" + p.getY() + "', " +
            "mapX='" + p.getMapX() + "', " +
            "mapY='" + p.getMapY() + "', " +
            "healX='" + p.getHealX() + "', " +
            "healY='" + p.getHealY() + "', " +
            "healMapX='" + p.getHealMapX() + "', " +
            "healMapY='" + p.getHealMapY() + "', " +
            "isSurfing='" + String.valueOf(p.isSurfing()) + "', " +
            "badges='" + badges + "' " +
            "WHERE id='" + p.getId() + "'");
        /*
         * Second, update the party
         */
        //Save all the Pokemon
        for(int i = 0; i < 6; i++) {
          if(p.getParty() != null && p.getParty()[i] != null) {
            if(p.getParty()[i].getDatabaseID() < 1) {
              //This is a new Pokemon, add it to the database
              if(saveNewPokemon(p.getParty()[i], p.getName(), m_database) < 1)
                return false;
            } else {
              //Old Pokemon, just update
              if(!savePokemon(p.getParty()[i], p.getName()))
                return false;
            }
          }
        }
        //Save all the Pokemon id's in the player's party
        if(p.getParty() != null) {
          m_database.query("UPDATE pn_party SET " +
              "pokemon0='" + (p.getParty()[0] != null ? p.getParty()[0].getDatabaseID() : -1) + "', " +
              "pokemon1='" + (p.getParty()[1] != null ? p.getParty()[1].getDatabaseID() : -1) + "', " +
              "pokemon2='" + (p.getParty()[2] != null ? p.getParty()[2].getDatabaseID() : -1) + "', " +
              "pokemon3='" + (p.getParty()[3] != null ? p.getParty()[3].getDatabaseID() : -1) + "', " +
              "pokemon4='" + (p.getParty()[4] != null ? p.getParty()[4].getDatabaseID() : -1) + "', " +
              "pokemon5='" + (p.getParty()[5] != null ? p.getParty()[5].getDatabaseID() : -1) + "' " +
              "WHERE member='" + p.getId() + "'");
        } else
          return true;
        /*
         * Save the player's bag
         */
        if(p.getBag() == null || !saveBag(p.getBag()))
          return false;
        /*
         * Finally, update all the boxes
         */
        if(p.getBoxes() != null) {
          for(int i = 0; i < 9; i++) {
            if(p.getBoxes()[i] != null) {
              /* Save all pokemon in box */
              for(int j = 0; j < p.getBoxes()[i].getPokemon().length; j++) {
                if(p.getBoxes()[i].getPokemon()[j] != null) {
                  if(p.getBoxes()[i].getPokemon()[j].getDatabaseID() < 1) {
                    /* This is a new Pokemon, create it in the database */
                    if(saveNewPokemon(p.getBoxes()[i].getPokemon(j), p.getName(), m_database) < 1)
                      return false;
                  } else {
                    /* Update an existing pokemon */
                    if(!savePokemon(p.getBoxes()[i].getPokemon()[j], p.getName())) {
                      return false;
                    }
                  }
                }
              }
            }
          }
        }
        //Dispose of the player object
        if(p.getMap() != null)
          p.getMap().removeChar(p);
        return true;
      } else
        return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 
  /**
   * Saves a pokemon to the database that didn't exist in it before
   * @param p
   */
  private int saveNewPokemon(Pokemon p, String currentTrainer, MySqlManager db) {
    try {
      /*
       * Due to issues with Pokemon not receiving abilities,
       * we're going to ensure they have one
       */
      if(p.getAbility() == null || p.getAbility().getName().equalsIgnoreCase("")) {
        String [] abilities = PokemonSpecies.getDefaultData().getPossibleAbilities(p.getSpeciesName());
            /* First select an ability randomly */
            String ab = "";
            if(abilities.length == 1)
              ab = abilities[0];
            else
              ab = abilities[DataService.getBattleMechanics().getRandom().nextInt(abilities.length)];
            p.setAbility(IntrinsicAbility.getInstance(ab), true);
      }
      /*
       * Insert the Pokemon into the database
       */
      db.query("INSERT INTO pn_pokemon" +
          "(name, speciesName, exp, baseExp, expType, isFainted, level, happiness, " +
          "gender, nature, abilityName, itemName, isShiny, currentTrainerName, originalTrainerName, date, contestStats)" +
          "VALUES (" +
          "'" + MySqlManager.parseSQL(p.getName()) +"', " +
          "'" + MySqlManager.parseSQL(p.getSpeciesName()) +"', " +
          "'" + String.valueOf(p.getExp()) +"', " +
          "'" + p.getBaseExp() +"', " +
          "'" + MySqlManager.parseSQL(p.getExpType().name()) +"', " +
          "'" + String.valueOf(p.isFainted()) +"', " +
          "'" + p.getLevel() +"', " +
          "'" + p.getHappiness() +"', " +
          "'" + p.getGender() +"', " +
          "'" + MySqlManager.parseSQL(p.getNature().getName()) +"', " +
          "'" + MySqlManager.parseSQL(p.getAbilityName()) +"', " +
          "'" + MySqlManager.parseSQL(p.getItemName()) +"', " +
          "'" + String.valueOf(p.isShiny()) +"', " +
          "'" + currentTrainer + "', " +
          "'" + MySqlManager.parseSQL(p.getOriginalTrainer()) + "', " +
          "'" + MySqlManager.parseSQL(p.getDateCaught()) + "', " +
          "'" + p.getContestStatsAsString() + "')");
      /*
       * Get the pokemon's database id and attach it to the pokemon.
       * This needs to be done so it can be attached to the player in the database later.
       */
      ResultSet result = db.query("SELECT * FROM pn_pokemon WHERE originalTrainerName='"  + MySqlManager.parseSQL(p.getOriginalTrainer()) +
          "' AND date='" + MySqlManager.parseSQL(p.getDateCaught()) + "' AND name='" + p.getSpeciesName() + "' AND exp='" +
          String.valueOf(p.getExp()) + "'");
      result.first();
      p.setDatabaseID(result.getInt("id"));
      db.query("UPDATE pn_pokemon SET move0='" + MySqlManager.parseSQL(p.getMove(0).getName()) +
          "', move1='" + (p.getMove(1) == null ? "null" : MySqlManager.parseSQL(p.getMove(1).getName())) +
          "', move2='" + (p.getMove(2) == null ? "null" : MySqlManager.parseSQL(p.getMove(2).getName())) +
          "', move3='" + (p.getMove(3) == null ? "null" : MySqlManager.parseSQL(p.getMove(3).getName())) +
          "', hp='" + p.getHealth() +
          "', atk='" + p.getStat(1) +
          "', def='" + p.getStat(2) +
          "', speed='" + p.getStat(3) +
          "', spATK='" + p.getStat(4) +
          "', spDEF='" + p.getStat(5) +
          "', evHP='" + p.getEv(0) +
          "', evATK='" + p.getEv(1) +
          "', evDEF='" + p.getEv(2) +
          "', evSPD='" + p.getEv(3) +
          "', evSPATK='" + p.getEv(4) +
          "', evSPDEF='" + p.getEv(5) +
          "' WHERE id='" + p.getDatabaseID() + "'");
      db.query("UPDATE pn_pokemon SET ivHP='" + p.getIv(0) +
          "', ivATK='" + p.getIv(1) +
          "', ivDEF='" + p.getIv(2) +
          "', ivSPD='" + p.getIv(3) +
          "', ivSPATK='" + p.getIv(4) +
          "', ivSPDEF='" + p.getIv(5) +
          "', pp0='" + p.getPp(0) +
          "', pp1='" + p.getPp(1) +
          "', pp2='" + p.getPp(2) +
          "', pp3='" + p.getPp(3) +
          "', maxpp0='" + p.getMaxPp(0) +
          "', maxpp1='" + p.getMaxPp(1) +
          "', maxpp2='" + p.getMaxPp(2) +
          "', maxpp3='" + p.getMaxPp(3) +
          "', ppUp0='" + p.getPpUpCount(0) +
          "', ppUp1='" + p.getPpUpCount(1) +
          "', ppUp2='" + p.getPpUpCount(2) +
          "', ppUp3='" + p.getPpUpCount(3) +
          "' WHERE id='" + p.getDatabaseID() + "'");
      return result.getInt("id");
    } catch (Exception e) {
      e.printStackTrace();
      return -1;
    }
  }
 
  /**
   * Updates a pokemon in the database
   * @param p
   */
  private boolean savePokemon(Pokemon p, String currentTrainer) {
    try {
      /*
       * Update the pokemon in the database
       */
      m_database.query("UPDATE pn_pokemon SET " +
          "name='" + MySqlManager.parseSQL(p.getName()) +"', " +
          "speciesName='" + MySqlManager.parseSQL(p.getSpeciesName()) +"', " +
          "exp='" + String.valueOf(p.getExp()) +"', " +
          "baseExp='" + p.getBaseExp() +"', " +
          "expType='" + MySqlManager.parseSQL(p.getExpType().name()) +"', " +
          "isFainted='" + String.valueOf(p.isFainted()) +"', " +
          "level='" + p.getLevel() +"', " +
          "happiness='" + p.getHappiness() +"', " +
          "itemName='" + MySqlManager.parseSQL(p.getItemName()) +"', " +
          "currentTrainerName='" + currentTrainer +"', " +
          "contestStats='" + p.getContestStatsAsString() +"' " +
          "WHERE id='" + p.getDatabaseID() + "'");
try {      m_database.query("UPDATE pn_pokemon SET move0='" + (p.getMove(0) == null ? "null" : MySqlManager.parseSQL(p.getMove(0).getName())) +
          "', move1='" + (p.getMove(1) == null ? "null" : MySqlManager.parseSQL(p.getMove(1).getName())) +
          "', move2='" + (p.getMove(2) == null ? "null" : MySqlManager.parseSQL(p.getMove(2).getName())) +
          "', move3='" + (p.getMove(3) == null ? "null" : MySqlManager.parseSQL(p.getMove(3).getName())) +
          "', hp='" + p.getHealth() +
          "', atk='" + p.getStat(1) +
          "', def='" + p.getStat(2) +
          "', speed='" + p.getStat(3) +
          "', spATK='" + p.getStat(4) +
          "', spDEF='" + p.getStat(5) +
          "', evHP='" + p.getEv(0) +
          "', evATK='" + p.getEv(1) +
          "', evDEF='" + p.getEv(2) +
          "', evSPD='" + p.getEv(3) +
          "', evSPATK='" + p.getEv(4) +
          "', evSPDEF='" + p.getEv(5) +
          "' WHERE id='" + p.getDatabaseID() + "'");
}
catch (NullPointerException e) {
  e.printStackTrace();
  System.out.println("Database is " + m_database);
  System.out.println("Pokemon object is " + p);
  System.out.println("Database ID is " + p.getDatabaseID());
    System.out.println("Pokemon name is " + p.getName());
  System.out.println("Pokemon moves are " + p.getMove(0).getName() + "|" + p.getMove(1).getName() + "|" + p.getMove(2).getName() + "|" + p.getMove(3).getName());
  System.out.println("', hp='" + p.getHealth() +
          "', atk='" + p.getStat(1) +
          "', def='" + p.getStat(2) +
          "', speed='" + p.getStat(3) +
          "', spATK='" + p.getStat(4) +
          "', spDEF='" + p.getStat(5) +
          "', evHP='" + p.getEv(0) +
          "', evATK='" + p.getEv(1) +
          "', evDEF='" + p.getEv(2) +
          "', evSPD='" + p.getEv(3) +
          "', evSPATK='" + p.getEv(4) +
          "', evSPDEF='" + p.getEv(5));
}
      m_database.query("UPDATE pn_pokemon SET ivHP='" + p.getIv(0) +
          "', ivATK='" + p.getIv(1) +
          "', ivDEF='" + p.getIv(2) +
          "', ivSPD='" + p.getIv(3) +
          "', ivSPATK='" + p.getIv(4) +
          "', ivSPDEF='" + p.getIv(5) +
          "', pp0='" + p.getPp(0) +
          "', pp1='" + p.getPp(1) +
          "', pp2='" + p.getPp(2) +
          "', pp3='" + p.getPp(3) +
          "', maxpp0='" + p.getMaxPp(0) +
          "', maxpp1='" + p.getMaxPp(1) +
          "', maxpp2='" + p.getMaxPp(2) +
          "', maxpp3='" + p.getMaxPp(3) +
          "', ppUp0='" + p.getPpUpCount(0) +
          "', ppUp1='" + p.getPpUpCount(1) +
          "', ppUp2='" + p.getPpUpCount(2) +
          "', ppUp3='" + p.getPpUpCount(3) +
          "' WHERE id='" + p.getDatabaseID() + "'");
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 
  /**
   * Saves a bag to the database.
   * @param b
   * @return
   */
  private boolean saveBag(Bag b) {
    try {
      //Destroy item data to prevent dupes.
      m_database.query("DELETE FROM pn_bag WHERE member='" + b.getMemberId() + "'");
      for(int i = 0; i < b.getItems().size(); i++) {
        if(b.getItems().get(i) != null) {
          /*
           * NOTE: Items are stored as values 1 - 999
           */
          m_database.query("INSERT INTO pn_bag (member,item,quantity) VALUES ('" +
              b.getMemberId()+"', '" +
              b.getItems().get(i).getItemNumber()+"', '"+
              b.getItems().get(i).getQuantity()+"')");
        }
      }
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

}
TOP

Related Classes of org.pokenet.server.network.LogoutManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.