public void saveToDB(boolean dc, boolean fromcs) {
        Connection con = DatabaseConnection.getConnection();

        PreparedStatement ps = null;
        PreparedStatement pse = null;
        ResultSet rs = null;
        String sql = null;
        try {
            con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            con.setAutoCommit(false);
            sql = "UPDATE characters SET" + " `level` = ?, `fame` = ?, `str` = ?, `dex` = ?, `luk` = ?," + //5
                    " `int` = ?, `exp` = ?, `hp` = ?, `mp` = ?, `storageap` = ?," + //10
                    " `ap` = ?, `skincolor` = ?, `job` = ?, `hair` = ?," + //14
                    " `face` = ?, `map` = ?, `meso` = ?, `spawnpoint` = ?, `party` = ?," + //19
                    " `reborns` = ?, `mobkilled` = ?, `bosskilled` = ?, `mutality` =?, `clonelimit` = ?," +//24
                    " `legend` = ?, `msi` = ?, `name` = ?, `pvpdeaths` = ?," + //28
                    " `pvpkills` = ?, `prefixshit` = ?, `autoap` = ?, `lmpoints` = ?, `taocheck` = ?, `gmsmode` = ?," + //34
                    " `lastdojostage` = ? , `dojopoints` = ?, `smega` = ?, `bqpoints` = ?," + //38
                    " `kpqpoints` = ?, `textcolour` = ?, `mission` = ?," +//41
                    " `exprate` = ?, `mesorate` = ?, `droprate` = ?, `bossrate` = ?," + // 45
                    " `maxhp` = ?, `maxmp` = ?" + //47
                    //      " `matchcardwins` = ?, `matchcardlosses` = ?, `matchcardties` = ?, `omokwins` = ?, `omoklosses` = ?, `omokties` = ?" + //46
                    " WHERE id = ?"; //48
         /*   sql = "INSERT INTO characters VALUES (`level`, `fame`, `str`, `dex`, `luk`," + //5
            " `int`, `exp`, `hp`, `mp`, `storageap`," + //10
            " `ap`, `skincolor`, `job`, `hair`," + //14
            " `face`, `map`, `meso`, `spawnpoint`, `party`," + //19
            " `reborns`, `mobkilled`, `bosskilled`, `mutality` =?, `clonelimit`," +//24
            " `legend`, `msi`, `name`, `pvpdeaths`," + //28
            " `pvpkills`, `prefixshit`, `autoap`, `shuriken`, `taocheck`, `gmsmode`," + //34
            " `lastdojostage` = ? , `dojopoints`, `smega`, `bqpoints`," + //38
            " `clan`, `kpqpoints`, `textcolour`)"*/
            ps = con.prepareStatement(sql);
            ps.setInt(1, level);
            ps.setInt(2, fame);
            ps.setInt(3, stats.str);
            ps.setInt(4, stats.dex);
            ps.setInt(5, stats.luk);
            ps.setInt(6, stats.int_);
            ps.setInt(7, exp); // exp
            ps.setInt(8, stats.hp);
            ps.setInt(9, stats.mp);
            ps.setInt(10, storageAp);
            ps.setInt(11, remainingAp);
            ps.setInt(12, skinColor);
            ps.setInt(13, job);
            ps.setInt(14, hair);
            ps.setInt(15, face);
            ps.setInt(16, map.getId()); // map
            ps.setInt(17, meso); // meso
            ps.setInt(18, initialSpawnPoint);
            if (party != null) {
                ps.setInt(19, party.getId());
            } else {
                ps.setInt(19, -1);
            }
            ps.setInt(20, reborn);
            ps.setInt(21, mobkilled);
            ps.setInt(22, bosskilled);
            ps.setByte(23, mutality);
            ps.setByte(24, clonelimit);
            ps.setString(25, legend);
            ps.setByte(26, maxstatitem);
            ps.setString(27, name);
            ps.setInt(28, pvpdeaths);
            ps.setInt(29, pvpkills);
            ps.setByte(30, prefixshit);
            ps.setByte(31, autoap);
            ps.setInt(32, lmpoints);
            int itemcount = getTaoOfSight();
            int difference = itemcount - taocheck;
            if ((difference > 100 && reborn < 5) || (difference > 1000 && reborn < 25) || (difference > 10000 && reborn < 100)) {
                if (isJounin()) {
                    client.getChannelServer().broadcastStaffPacket(MaplePacketCreator.serverNotice(1, "[Report] " + name + " has received " + difference + " more chickens more than he originated since his last save."));
                }
            }
            ps.setInt(33, itemcount);
            ps.setByte(34, GMSMode);
            ps.setInt(35, lastDojoStage);
            ps.setInt(36, dojoPoints);
            ps.setByte(37, smega);
            ps.setInt(38, bossPoints);
            ps.setInt(39, kpqpoints);
            ps.setByte(40, textColour);
            ps.setByte(41, mission);
            ps.setInt(42, expBoost);
            ps.setInt(43, mesoBoost);
            ps.setInt(44, dropBoost);
            ps.setInt(45, bdropBoost);
            ps.setInt(46, stats.maxhp);
            ps.setInt(47, stats.maxmp);
            ps.setInt(48, id);
            int updateRows = ps.executeUpdate();
            if (updateRows < 1) {
                throw new DatabaseException("Character not in database (" + id + ")");
            }
            for (final MaplePet petz : pets) {
                if (petz.getSummoned()) {
                    petz.saveToDb(); // Only save those summoned :P
                }
            }

            deleteWhereCharacterId(con, "DELETE FROM inventoryitems WHERE characterid = ?");
            ps = con.prepareStatement("INSERT INTO inventoryitems (characterid, itemid, inventorytype, position, quantity, owner, GM_Log, petid, expiredate, flag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", DatabaseConnection.RETURN_GENERATED_KEYS);
            pse = con.prepareStatement("INSERT INTO inventoryequipment VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

            for (final MapleInventory iv : inventory) {
                ps.setInt(3, iv.getType().getType());
                for (final IItem item : iv.list()) {
                    ps.setInt(1, id);
                    ps.setInt(2, item.getItemId());
                    ps.setInt(4, item.getPosition());
                    ps.setInt(5, item.getQuantity());
                    ps.setString(6, item.getOwner());
                    ps.setString(7, item.getGMLog());
                    ps.setInt(8, item.getPet() != null ? item.getPet().getUniqueId() : -1);
                    ps.setLong(9, item.getExpiration());
                    ps.setByte(10, item.getFlag());
                    ps.executeUpdate();

                    rs = ps.getGeneratedKeys();
                    int itemid;
                    if (rs.next()) {
                        itemid = rs.getInt(1);
                    } else {
                        throw new DatabaseException("Inserting char failed.");
                    }

                    if (iv.getType().equals(MapleInventoryType.EQUIP) || iv.getType().equals(MapleInventoryType.EQUIPPED)) {
                        pse.setInt(1, itemid);
                        IEquip equip = (IEquip) item;
                        pse.setInt(2, equip.getUpgradeSlots());
                        pse.setInt(3, equip.getLevel());
                        pse.setInt(4, equip.getStr());
                        pse.setInt(5, equip.getDex());
                        pse.setInt(6, equip.getInt());
                        pse.setInt(7, equip.getLuk());
                        pse.setInt(8, equip.getHp());
                        pse.setInt(9, equip.getMp());
                        pse.setInt(10, equip.getWatk());
                        pse.setInt(11, equip.getMatk());
                        pse.setInt(12, equip.getWdef());
                        pse.setInt(13, equip.getMdef());
                        pse.setInt(14, equip.getAcc());
                        pse.setInt(15, equip.getAvoid());
                        pse.setInt(16, equip.getHands());
                        pse.setInt(17, equip.getSpeed());
                        pse.setInt(18, equip.getJump());
                        pse.setInt(19, equip.getRingId());
                        pse.setInt(20, equip.getViciousHammer());
                        pse.setInt(21, equip.getItemLevel());
                        pse.setInt(22, equip.getItemEXP());
                        pse.executeUpdate();
                    }
                }
            }
            ps.close();
            pse.close();

            if (dc && getAllCoolDowns().size() > 0) {
                for (final PlayerCoolDownValueHolder cooling : getAllCoolDowns()) {
                    ps = con.prepareStatement("INSERT INTO skills_cooldowns (charid, SkillID, StartTime, length) VALUES (?, ?, ?, ?)");
                    ps.setInt(1, getId());
                    ps.setInt(2, cooling.skillId);
                    ps.setLong(3, cooling.startTime);
                    ps.setLong(4, cooling.length);
                    ps.addBatch();
                }
                ps.executeBatch();
                ps.close();
            }



            byte kb = (byte) ((this.GMSMode > 0) ? 1 : (this.job > 910) ? 2 : 3);
            keylayout.saveKeys(id, kb);


            deleteWhereCharacterId(con, "DELETE FROM skillmacros WHERE characterid = ?");
            for (int i = 0; i < 5; i++) {
                SkillMacro macro = skillMacros[i];
                if (macro != null) {
                    ps = con.prepareStatement("INSERT INTO skillmacros" + " (characterid, skill1, skill2, skill3, name, shout, position, kb) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
                    ps.setInt(1, id);
                    ps.setInt(2, macro.getSkill1());
                    ps.setInt(3, macro.getSkill2());
                    ps.setInt(4, macro.getSkill3());
                    ps.setString(5, macro.getName());
                    ps.setInt(6, macro.getShout());
                    ps.setInt(7, i);
                    ps.addBatch();
                }
            }
            ps.executeBatch();
            ps.close();


            deleteWhereCharacterId(con, "DELETE FROM savedlocations WHERE characterid = ?");
            ps = con.prepareStatement("INSERT INTO savedlocations (characterid, `locationtype`, `map`) VALUES (?, ?, ?)");
            ps.setInt(1, id);
            for (final SavedLocationType savedLocationType : SavedLocationType.values()) {
                if (savedLocations[savedLocationType.ordinal()] != -1) {
                    ps.setString(2, savedLocationType.name());
                    ps.setInt(3, savedLocations[savedLocationType.ordinal()]);
                    ps.addBatch();
                }
            }
            ps.executeBatch();
            ps.close();

            mount.saveMount(id);

            deleteWhereCharacterId(con, "DELETE FROM buddies WHERE characterid = ? AND pending = 0");
            ps = con.prepareStatement("INSERT INTO buddies (characterid, `buddyid`, `group`, `pending`) VALUES (?, ?, ?, 0)");
            ps.setInt(1, id);
            for (BuddylistEntry entry : buddylist.getBuddies()) {
                if (entry.isVisible()) {
                    ps.setInt(2, entry.getCharacterId());
                    ps.setString(3, entry.getGroup());
                    ps.addBatch();
                }
            }
            ps.executeBatch();

            if (autobuffchange) {
                deleteWhereCharacterId(con, "DELETE FROM autobuffs WHERE characterid = ?");
                ps = con.prepareStatement("INSERT INTO autobuffs (characterid, skillid) VALUES (?, ?)");
                ps.setInt(1, id);
                for (int buff : autobuffs) {
                    ps.setInt(2, buff);
                    ps.addBatch();
                }
                ps.executeBatch();
                ps.close();
            }

            ps = con.prepareStatement("UPDATE accounts SET `cardNX` = ?, `maplePoints` = ?, `paypalNX` = ?, `village` = ?, `ninjatensu` = ?, `dpoints` = ?, `damount` = ?, `jqfinished` = ?, `jqpoints` = ?, `lastjq` = ? WHERE id = ?");
            ps.setInt(1, cardNX);
            ps.setInt(2, maplePoints);
            ps.setInt(3, paypalNX);
            ps.setInt(4, village);
            ps.setInt(5, ninjatensu);
            ps.setShort(6, dpoints);
            ps.setShort(7, damount);
            ps.setInt(8, jqFinished);
            ps.setShort(9, jqPoints);
            ps.setInt(10, lastjq);
            ps.setInt(11, client.getAccID());
            ps.executeUpdate();

            if (storage != null) {
                storage.saveToDB();
            }

            deleteWhereCharacterId(con, "DELETE FROM wishlist WHERE characterid = ?");
            for (int i = 0; i < getWishlistSize(); i++) {
                ps = con.prepareStatement("INSERT INTO wishlist(characterid, sn) VALUES(?, ?) ");
                ps.setInt(1, getId());
                ps.setInt(2, wishlist[i]);
                ps.addBatch();
            }
            ps.executeBatch();
            ps.close();

            con.commit();
        } catch (Exception e) {
            System.err.println("[charsave] Error saving character data" + e);
            try {
                con.rollback();
            } catch (SQLException e1) {
                System.err.println("[charsave] Error Rolling back" + e1);
            }
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
                con.setAutoCommit(true);
                con.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
            } catch (SQLException e) {
                System.err.println("[charsave] Error going back to autocommit mode" + e);
            }
        }
    }