public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) {
        final MapleCharacter ret = new MapleCharacter(channelserver);
        ret.client = client;
        ret.id = charid;

        Connection con = DatabaseConnection.getConnection();
        PreparedStatement ps = null;
        PreparedStatement pse = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement("SELECT * FROM characters WHERE id = ?");
            ps.setInt(1, charid);
            rs = ps.executeQuery();
            if (!rs.next()) {
                throw new RuntimeException("Loading the Char Failed (char not found)");
            }
            ret.name = rs.getString("name");
            ret.level = rs.getShort("level");
            if (ret.level >= 255) {
                ret.level = 255;
            }
            if (ret.level < 1) {
                ret.level = 1;
            }
            ret.fame = rs.getInt("fame");
            ret.stats.str = rs.getInt("str");
            ret.stats.dex = rs.getInt("dex");
            ret.stats.int_ = rs.getInt("int");
            ret.stats.luk = rs.getInt("luk");
            ret.exp = rs.getInt("exp");
            ret.stats.hp = rs.getInt("hp");
            ret.stats.mp = rs.getInt("mp");
            ret.stats.maxhp = rs.getInt("maxhp");
            ret.stats.maxmp = rs.getInt("maxmp");
            ret.storageAp = rs.getInt("storageap");
            ret.remainingAp = rs.getInt("ap");
            ret.meso = rs.getInt("meso");
            ret.skinColor = rs.getInt("skincolor");
            ret.job = rs.getInt("job");
            ret.hair = rs.getInt("hair");
            ret.face = rs.getInt("face");
            ret.accountid = rs.getInt("accountid");
            ret.mapid = rs.getInt("map");
            ret.initialSpawnPoint = rs.getInt("spawnpoint");
            ret.world = rs.getInt("world");
            ret.reborn = rs.getInt("reborns");
            ret.mobkilled = rs.getInt("mobkilled");
            ret.bosskilled = rs.getInt("bosskilled");
            ret.mutality = rs.getByte("mutality");
            ret.guildid = rs.getInt("guildid");
            ret.guildrank = rs.getByte("guildrank");
            ret.allianceRank = rs.getByte("allianceRank");
            ret.clonelimit = rs.getByte("clonelimit");
            ret.rasengan = rs.getByte("rasengan");
            ret.legend = rs.getString("legend");
            ret.maxstatitem = rs.getByte("msi");
            ret.lmpoints = rs.getInt("lmpoints");
            ret.pvpdeaths = rs.getInt("pvpdeaths");
            ret.pvpkills = rs.getInt("pvpkills");
            ret.prefixshit = rs.getByte("prefixshit");
            ret.autoap = rs.getByte("autoap");
            ret.jobrank = rs.getInt("jobrank");
            ret.jobrankmove = rs.getInt("jobrankmove");
            ret.rank = rs.getInt("rank");
            ret.rankmove = rs.getInt("rankmove");
            ret.buddylist = new BuddyList(255);
            if (ret.guildid > 0) {
                ret.mgc = new MapleGuildCharacter(ret);
            }
            if (channelserver) {
                ret.createdate = rs.getString("createdate");
                ret.previousnames = rs.getString("previousnames");
                if (ret.previousnames == null || ret.previousnames.length() < 2) {
                    ret.previousnames = "||";
                }
                ret.taocheck = rs.getInt("taocheck");
                ret.GMSMode = rs.getByte("gmsmode");
                ret.lastDojoStage = rs.getByte("lastdojostage");
                ret.dojoPoints = rs.getInt("dojopoints");
                ret.taorank = rs.getInt("taorank");
                ret.clantaorank = rs.getInt("clantaorank");
                ret.smega = rs.getByte("smega");
                ret.bossPoints = rs.getInt("bqpoints");
                ret.kpqpoints = rs.getInt("kpqpoints");
                ret.expBoost = rs.getInt("exprate");
                ret.mesoBoost = rs.getInt("mesorate");
                ret.dropBoost = rs.getInt("droprate");
                ret.bdropBoost = rs.getInt("bossrate");
                ret.textColour = rs.getByte("textcolour");
                ret.mission = rs.getByte("mission");
                doLoginMapCheck(ret);
                int partyid = rs.getInt("party");
                if (partyid >= 0) {
                    MapleParty party = null;
                    try {
                        party = client.getChannelServer().getWorldInterface().getParty(partyid);
                    } catch (RemoteException remoteException) {
                    }
                    if (party != null && party.getMemberById(ret.id) != null) {
                        ret.party = party;
                    }
                }
            }
            rs.close();
            ps.close();
            ps = con.prepareStatement("SELECT * FROM accounts WHERE id = ?");
            ps.setInt(1, ret.accountid);
            rs = ps.executeQuery();
            byte gmm = 0;
            if (rs.next()) {
                ret.getClient().setAccountName(rs.getString("name"));
                ret.paypalNX = rs.getInt("paypalNX");
                ret.maplePoints = rs.getInt("maplePoints");
                ret.cardNX = rs.getInt("cardNX");
                ret.ninjatensu = rs.getByte("ninjatensu");
                ret.dpoints = rs.getShort("dpoints");
                ret.damount = rs.getShort("damount");
                ret.jqPoints = rs.getShort("jqpoints");
                ret.jqFinished = rs.getInt("jqfinished");
                ret.lastjq = rs.getByte("lastjq");
                ret.footnote = rs.getString("footnote");
                ret.village = rs.getByte("village");
                ret.gmLevel = rs.getByte("gm");
            }
            rs.close();
            ps.close();
            if ((ret.job == 900 || ret.job == 910) && gmm < 3) {
                ret.job = 0;
            }


            if (channelserver) {
                if (ret.isGenin()) {
                    ps = con.prepareStatement("SELECT skillid FROM autobuffs WHERE characterid = ?");
                    ps.setInt(1, charid);
                    rs = ps.executeQuery();
                    while (rs.next()) {
                        ret.autobuffs.add(rs.getInt("skillid"));
                    }
                    rs.close();
                    ps.close();
                }


                ps = con.prepareStatement("SELECT * FROM inventoryitems LEFT JOIN inventoryequipment USING (inventoryitemid) WHERE characterid = ?");
                ps.setInt(1, charid);
                rs = ps.executeQuery();

                long expiration;
                MapleInventoryType type;
                Item item;
                MaplePet pet;

                while (rs.next()) {
                    type = MapleInventoryType.getByType(rs.getByte("inventorytype"));
                    expiration = rs.getLong("expiredate");

                    if (type.equals(MapleInventoryType.EQUIP) || type.equals(MapleInventoryType.EQUIPPED)) {
                        final Equip equip = new Equip(rs.getInt("itemid"), rs.getByte("position"), rs.getInt("ringid"), rs.getByte("flag"));
                        equip.setOwner(rs.getString("owner"));
                        equip.setQuantity(rs.getShort("quantity"));
                        equip.setAcc(rs.getShort("acc"));
                        equip.setAvoid(rs.getShort("avoid"));
                        equip.setDex(rs.getShort("dex"));
                        equip.setHands(rs.getShort("hands"));
                        equip.setHp(rs.getShort("hp"));
                        equip.setInt(rs.getShort("int"));
                        equip.setJump(rs.getShort("jump"));
                        equip.setLuk(rs.getShort("luk"));
                        equip.setMatk(rs.getShort("matk"));
                        equip.setMdef(rs.getShort("mdef"));
                        equip.setMp(rs.getShort("mp"));
                        equip.setSpeed(rs.getShort("speed"));
                        equip.setStr(rs.getShort("str"));
                        equip.setWatk(rs.getShort("watk"));
                        equip.setWdef(rs.getShort("wdef"));
                        equip.setItemLevel(rs.getByte("itemLevel"));
                        equip.setItemEXP(rs.getShort("itemEXP"));
                        equip.setViciousHammer(rs.getByte("ViciousHammer"));
                        equip.setUpgradeSlots(rs.getByte("upgradeslots"));
                        equip.setLevel(rs.getByte("level"));
                        equip.setExpiration(expiration);
                        equip.setGMLog(rs.getString("GM_Log"));
                        ret.getInventory(type).addFromDB(equip);
                    } else {
                        item = new Item(rs.getInt("itemid"), rs.getByte("position"), rs.getShort("quantity"), rs.getByte("flag"));
                        item.setOwner(rs.getString("owner"));
                        item.setExpiration(expiration);
                        item.setGMLog(rs.getString("GM_Log"));
                        ret.getInventory(type).addFromDB(item);

                        if (rs.getInt("petid") > -1) {
                            pet = MaplePet.loadFromDb(item.getItemId(), rs.getInt("petid"), item.getPosition());
                            ret.pets.add(pet);
                            item.setPet(pet);
                        }
                    }
                }
                rs.close();
                ps.close();
                if (channelserver) {
                    ret.maxSkills(false);
                    ps = con.prepareStatement("SELECT `key`,`type`,`action` FROM keymap WHERE characterid = ? AND kb = ?");
                    ps.setInt(1, charid);
                    byte kb = (byte) ((ret.GMSMode > 0) ? 1 : (ret.job > 910) ? 2 : 3);
                    ps.setByte(2, kb);
                    rs = ps.executeQuery();
                    final Map<Integer, MapleKeyBinding> keyb = ret.keylayout.Layout();
                    while (rs.next()) {
                        keyb.put(Integer.valueOf(rs.getInt("key")), new MapleKeyBinding(rs.getInt("type"), rs.getInt("action")));
                    }
                    rs.close();
                    ps.close();


                    ps = con.prepareStatement("SELECT * FROM skillmacros WHERE characterid = ? AND kb = ?");
                    ps.setInt(1, charid);
                    ps.setByte(2, kb);
                    rs = ps.executeQuery();
                    int position;
                    while (rs.next()) {
                        position = rs.getInt("position");
                        SkillMacro macro = new SkillMacro(rs.getInt("skill1"), rs.getInt("skill2"), rs.getInt("skill3"), rs.getString("name"), rs.getInt("shout"), position);
                        ret.skillMacros[position] = macro;
                    }
                    rs.close();
                    ps.close();



                    ps = con.prepareStatement("SELECT `locationtype`,`map` FROM savedlocations WHERE characterid = ?");
                    ps.setInt(1, charid);
                    rs = ps.executeQuery();
                    while (rs.next()) {
                        ret.savedLocations[SavedLocationType.valueOf(rs.getString("locationtype")).ordinal()] = rs.getInt("map");
                    }
                    rs.close();
                    ps.close();


                    ps = con.prepareStatement("SELECT `characterid_to`,`when` FROM famelog WHERE characterid = ? AND DATEDIFF(NOW(),`when`) < 30");
                    ps.setInt(1, charid);
                    rs = ps.executeQuery();
                    ret.lastfametime = 0;
                    ret.lastmonthfameids = new ArrayList<Integer>(31);
                    while (rs.next()) {
                        ret.lastfametime = Math.max(ret.lastfametime, rs.getTimestamp("when").getTime());
                        ret.lastmonthfameids.add(Integer.valueOf(rs.getInt("characterid_to")));
                    }
                    rs.close();
                    ps.close();

                    ret.buddylist.loadFromDb(charid);
                    ret.storage = MapleStorage.loadStorage(ret.accountid);
                }
                ps = con.prepareStatement("SELECT sn FROM wishlist WHERE characterid = ?");
                ps.setInt(1, charid);
                rs = ps.executeQuery();
                int i = 0;
                while (rs.next()) {
                    ret.wishlist[i] = rs.getInt("sn");
                    i++;
                }
                while (i < 10) {
                    ret.wishlist[i] = 0;
                    i++;
                }
                rs.close();
                ps.close();

                ps = con.prepareStatement("SELECT mapid FROM trocklocations WHERE characterid = ?");
                ps.setInt(1, charid);
                rs = ps.executeQuery();
                int r = 0;
                while (rs.next()) {
                    ret.rocks[r] = rs.getInt("mapid");
                    r++;
                }
                while (r < 10) {
                    ret.rocks[r] = 999999999;
                    r++;
                }
                rs.close();
                ps.close();

                ps = con.prepareStatement("SELECT * FROM mountdata WHERE characterid = ?");
                ps.setInt(1, charid);
                rs = ps.executeQuery();
                if (!rs.next()) {
                    throw new RuntimeException("No mount data found on SQL column");
                }
                final IItem mount = ret.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -22);
                ret.mount = new MapleMount(ret, mount != null ? mount.getItemId() : 0, 1004, rs.getInt("Fatigue"), rs.getInt("Level"), rs.getInt("Exp"));
                ps.close();
                rs.close();

                ret.stats.recalcLocalStats();
                ret.silentEnforceMaxHpMp();
                ret.resetBattleshipHp();
            } else {
                ps = con.prepareStatement("SELECT * FROM inventoryitems LEFT JOIN inventoryequipment USING (inventoryitemid) WHERE characterid = ? AND inventorytype = -1");
                ps.setInt(1, charid);
                rs = ps.executeQuery();

                MapleInventoryType type;
                while (rs.next()) {
                    type = MapleInventoryType.getByType(rs.getByte("inventorytype"));
                    if (type.equals(MapleInventoryType.EQUIP) || type.equals(MapleInventoryType.EQUIPPED)) {
                        final Equip equip = new Equip(rs.getInt("itemid"), rs.getByte("position"), rs.getInt("ringid"), rs.getByte("flag"));
                        ret.getInventory(type).addFromDB(equip);
                    }
                }
                rs.close();
                ps.close();
            }
        } catch (SQLException ess) {
            ess.printStackTrace();
            System.out.println("Failed to load character..");
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                }
                if (pse != null) {
                    pse.close();
                }
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException ignore) {
            }
        }
        return ret;
    }