Cheat Engine

The Underground Site of Cheat Engine


    Guild BBS leak

    Share

    Admin
    Admin

    Posts : 43
    Join date : 2009-05-18

    Guild BBS leak

    Post  Admin on Tue May 19, 2009 6:20 am

    This fixes server crashing with people spamming BBS with packet editing due to memory leak[/COLOR]
    Note : I'm using ystem.err.println(); , change it slfj-api if you want.


    Replace your BBSOperationHandler with this :
    package net.sf.odinms.net.channel.handler;import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import net.sf.odinms.client.MapleCharacter;
    import net.sf.odinms.client.MapleClient;
    import net.sf.odinms.database.DatabaseConnection;
    import net.sf.odinms.net.AbstractMaplePacketHandler;
    import net.sf.odinms.tools.MaplePacketCreator;
    import net.sf.odinms.tools.data.input.SeekableLittleEndianAccessor;
    public class BBSOperationHandler extends AbstractMaplePacketHandler {
    private String correctLength(String in, int maxSize) {
    if (in.length() > maxSize)
    return in.substring(0, maxSize);
    return in;
    }
    @Override
    public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    if (c.getPlayer().getGuildId() <= 0) {
    return; // expelled while viewing bbs or hax
    }
    int localthreadid = 0;
    switch (slea.readByte()) {
    case 0: // start a new post
    boolean bEdit = slea.readByte() == 1 ? true : false;
    if (bEdit) {
    localthreadid = slea.readInt();
    }
    boolean bNotice = slea.readByte() == 1 ? true : false;
    String title = correctLength(slea.readMapleAsciiString(), 25);
    String text = correctLength(slea.readMapleAsciiString(), 600);
    int icon = slea.readInt();
    if (icon >= 0x64 && icon <= 0x6a) {
    if (!c.getPlayer().haveItem(5290000 + icon - 0x64, 1, false, true))
    return; // hax, using an nx icon that s/he doesn't have
    } else if (!(icon >= 0 && icon <= 2))
    return; // hax, using an invalid icon
    if (!bEdit) {
    newBBSThread(c, title, text, icon, bNotice);
    } else {
    editBBSThread(c, title, text, icon, localthreadid);
    }
    break;
    case 1: // delete a thread
    localthreadid = slea.readInt();
    deleteBBSThread(c, localthreadid);
    break;
    case 2: // list threads
    int start = slea.readInt();
    listBBSThreads(c, start * 10);
    break;
    case 3: // list thread + reply, followed by id (int)
    localthreadid = slea.readInt();
    displayThread(c, localthreadid, true);
    break;
    case 4: // reply
    localthreadid = slea.readInt();
    text = correctLength(slea.readMapleAsciiString(), 25);
    newBBSReply(c, localthreadid, text);
    break;
    case 5: // delete reply
    localthreadid = slea.readInt(); // we don't use this
    int replyid = slea.readInt();
    deleteBBSReply(c, replyid);
    break;
    }
    }
    private static void listBBSThreads(MapleClient c, int start) {
    try {
    Connection con = DatabaseConnection.getConnection();
    PreparedStatement ps = con.prepareStatement("SELECT * FROM bbs_threads WHERE guildid = ? ORDER BY localthreadid DESC");
    ps.setInt(1, c.getPlayer().getGuildId());
    ResultSet rs = ps.executeQuery();
    if (rs.next()) {
    c.getSession().write(MaplePacketCreator.BBSThreadList(rs, start));
    } else {
    c.getSession().write(MaplePacketCreator.BBS_noResult());
    }
    rs.close();
    ps.close();
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }
    private static void newBBSReply(MapleClient c, int localthreadid, String text) {
    if (c.getPlayer().getGuildId() <= 0) {
    return;
    }
    Connection con = DatabaseConnection.getConnection();
    try {
    PreparedStatement ps = con.prepareStatement("SELECT threadid FROM bbs_threads WHERE guildid = ? AND localthreadid = ?");
    ps.setInt(1, c.getPlayer().getGuildId());
    ps.setInt(2, localthreadid);
    ResultSet threadRS = ps.executeQuery();
    if (!threadRS.next()) {
    threadRS.close();
    ps.close();
    return; // thread no longer exists, deleted?
    }
    int threadid = threadRS.getInt("threadid");
    threadRS.close();
    ps.close();
    ps = con.prepareStatement("INSERT INTO bbs_replies (`threadid`, `postercid`, `timestamp`, `content`) VALUES " + "(?, ?, ?, ?)");
    ps.setInt(1, threadid);
    ps.setInt(2, c.getPlayer().getId());
    ps.setLong(3, System.currentTimeMillis());
    ps.setString(4, text);
    ps.execute();
    ps.close();
    ps = con.prepareStatement("UPDATE bbs_threads SET replycount = replycount + 1 WHERE threadid = ?");
    ps.setInt(1, threadid);
    ps.execute();
    ps.close();

    displayThread(c, localthreadid, true);
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }
    private static void editBBSThread(MapleClient c, String title, String text, int icon, int localthreadid) {
    if (c.getPlayer().getGuildId() <= 0) {
    return; // expelled while viewing?
    }
    try {
    Connection con = DatabaseConnection.getConnection();
    PreparedStatement ps = con.prepareStatement("UPDATE bbs_threads SET " + "`name` = ?, `timestamp` = ?, " + "`icon` = ?, " + "`startpost` = ? WHERE guildid = ? AND localthreadid = ? AND (postercid = ? OR ?)");
    ps.setString(1, title);
    ps.setLong(2, System.currentTimeMillis());
    ps.setInt(3, icon);
    ps.setString(4, text);
    ps.setInt(5, c.getPlayer().getGuildId());
    ps.setInt(6, localthreadid);
    ps.setInt(7, c.getPlayer().getId());
    ps.setBoolean(8, c.getPlayer().getGuildRank() <= 2);
    ps.execute();
    ps.close();

    displayThread(c, localthreadid, true);
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }
    private static void newBBSThread(MapleClient c, String title, String text, int icon, boolean bNotice) {
    if (c.getPlayer().getGuildId() <= 0) {
    return; // expelled while viewing?
    }
    int nextId = 0;
    try {
    Connection con = DatabaseConnection.getConnection();
    PreparedStatement ps;
    if (!bNotice) { // notice's local id is always 0, so we don't need to fetch it
    ps = con.prepareStatement("SELECT MAX(localthreadid) AS lastLocalId FROM bbs_threads WHERE guildid = ?");
    ps.setInt(1, c.getPlayer().getGuildId());
    ResultSet rs = ps.executeQuery();
    rs.next();
    nextId = rs.getInt("lastLocalId") + 1;
    rs.close();
    ps.close();
    }
    ps = con.prepareStatement("INSERT INTO bbs_threads (`postercid`, `name`, `timestamp`, `icon`, `startpost`, " + "`guildid`, `localthreadid`) VALUES(?, ?, ?, ?, ?, ?, ?)");
    ps.setInt(1, c.getPlayer().getId());
    ps.setString(2, title);
    ps.setLong(3, System.currentTimeMillis());
    ps.setInt(4, icon);
    ps.setString(5, text);
    ps.setInt(6, c.getPlayer().getGuildId());
    ps.setInt(7, nextId);
    ps.execute();
    ps.close();
    displayThread(c, nextId, true);
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }
    private static void deleteBBSThread(MapleClient c, int localthreadid) {
    if (c.getPlayer().getGuildId() <= 0) {
    return;
    }
    Connection con = DatabaseConnection.getConnection();
    try {
    PreparedStatement ps = con.prepareStatement("SELECT threadid, postercid FROM bbs_threads WHERE guildid = ? AND localthreadid = ?");
    ps.setInt(1, c.getPlayer().getGuildId());
    ps.setInt(2, localthreadid);
    ResultSet threadRS = ps.executeQuery();
    if (!threadRS.next()) {
    threadRS.close();
    ps.close();
    return; // thread no longer exists, deleted?
    }
    if (c.getPlayer().getId() != threadRS.getInt("postercid") && c.getPlayer().getGuildRank() > 2) {
    threadRS.close();
    ps.close();
    return; // [hax] deleting a thread that he didn't make
    }
    int threadid = threadRS.getInt("threadid");
    threadRS.close();
    ps.close();
    ps = con.prepareStatement("DELETE FROM bbs_replies WHERE threadid = ?");
    ps.setInt(1, threadid);
    ps.execute();
    ps.close();
    ps = con.prepareStatement("DELETE FROM bbs_threads WHERE threadid = ?");
    ps.setInt(1, threadid);
    ps.execute();
    ps.close();
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }
    private static void deleteBBSReply(MapleClient c, int replyid) {
    if (c.getPlayer().getGuildId() <= 0) {
    return;
    }
    int threadid;
    Connection con = DatabaseConnection.getConnection();
    try {
    PreparedStatement ps = con.prepareStatement("SELECT postercid, threadid FROM bbs_replies WHERE replyid = ?");
    ps.setInt(1, replyid);
    ResultSet rs = ps.executeQuery();
    if (!rs.next()) {
    rs.close();
    ps.close();
    return; // thread no longer exists, deleted?
    }
    if (c.getPlayer().getId() != rs.getInt("postercid") && c.getPlayer().getGuildRank() > 2) {
    rs.close();
    ps.close();
    return; // [hax] deleting a reply that he didn't make
    }
    threadid = rs.getInt("threadid");
    rs.close();
    ps.close();
    ps = con.prepareStatement("DELETE FROM bbs_replies WHERE replyid = ?");
    ps.setInt(1, replyid);
    ps.execute();
    ps.close();
    ps = con.prepareStatement("UPDATE bbs_threads SET replycount = replycount - 1 WHERE threadid = ?");
    ps.setInt(1, threadid);
    ps.execute();
    ps.close();

    displayThread(c, threadid, false);
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    }
    }


    Last edited by Admin on Tue May 19, 2009 6:21 am; edited 1 time in total

    Admin
    Admin

    Posts : 43
    Join date : 2009-05-18

    Re: Guild BBS leak

    Post  Admin on Tue May 19, 2009 6:20 am

    public static void displayThread(MapleClient c, int threadid, boolean bIsThreadIdLocal) {
    if (c.getPlayer().getGuildId() <= 0) {
    return;
    }
    Connection con = DatabaseConnection.getConnection();
    try {
    PreparedStatement ps = con.prepareStatement("SELECT * FROM bbs_threads WHERE guildid = ? AND " +
    (bIsThreadIdLocal ? "local" : "") + "threadid = ?");
    ps.setInt(1, c.getPlayer().getGuildId());
    ps.setInt(2, threadid);
    ResultSet threadRS = ps.executeQuery();

    if (!threadRS.next()) {
    threadRS.close();
    ps.close();
    return; // thread no longer exists, deleted?
    }
    ResultSet repliesRS = null;
    PreparedStatement ps2 = null;
    if (threadRS.getInt("replycount") > 0) {
    ps2 = con.prepareStatement("SELECT * FROM bbs_replies WHERE threadid = ?");
    ps2.setInt(1, !bIsThreadIdLocal ? threadid : threadRS.getInt("threadid"));
    repliesRS = ps2.executeQuery();
    // the lack of repliesRS.next() is intentional
    }
    c.getSession().write(MaplePacketCreator.showThread(bIsThreadIdLocal ? threadid : threadRS.getInt("localthreadid"), threadRS, repliesRS));
    ps.close();
    threadRS.close();
    if (ps2 != null) {
    ps2.close();
    }
    } catch (SQLException se) {
    System.err.println("SQLException: " + se.getLocalizedMessage() + se);
    } catch (RuntimeException re) {
    System.err.println("The number of reply rows does not match the replycount in thread. ThreadId = " + re.getMessage() + re);
    try {
    PreparedStatement ps = con.prepareStatement("DELETE FROM bbs_threads WHERE threadid = ?");
    ps.setInt(1, Integer.parseInt(re.getMessage()));
    ps.execute();
    ps.close();
    ps = con.prepareStatement("DELETE FROM bbs_replies WHERE threadid = ?");
    ps.setInt(1, Integer.parseInt(re.getMessage()));
    ps.execute();
    ps.close();
    } catch (SQLException e) {
    }
    }
    }
    }

    In MaplePacketCreator, add/ replace if you don't have..
    public static MaplePacket BBS_noResult() {
    MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.BBS_OPERATION.getValue());
    mplew.write(0x06);
    mplew.write(0);
    mplew.writeInt(0);
    mplew.writeInt(0);
    return mplew.getPacket();
    }
    public static MaplePacket BBSThreadList(ResultSet rs, int start) throws SQLException {
    MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
    mplew.writeShort(SendPacketOpcode.BBS_OPERATION.getValue());
    mplew.write(0x06);
    int threadCount = rs.getRow();

    if (rs.getInt("localthreadid") == 0) { //has a notice
    mplew.write(1);
    mplew.writeInt(rs.getInt("localthreadid"));
    mplew.writeInt(rs.getInt("postercid"));
    mplew.writeMapleAsciiString(rs.getString("name"));
    mplew.writeLong(MaplePacketCreator.getKoreanTimestamp(rs.getLong("timestamp")));
    mplew.writeInt(rs.getInt("icon"));
    mplew.writeInt(rs.getInt("replycount"));
    threadCount--; //one thread didn't count (because it's a notice)
    } else {
    mplew.write(0);
    }
    if (!rs.absolute(start + 1)) { //seek to the thread before where we start
    rs.first(); //uh, we're trying to start at a place past possible
    start = 0;
    }
    mplew.writeInt(threadCount);
    mplew.writeInt(Math.min(10, threadCount - start));

    for (int i = 0; i < Math.min(10, threadCount - start); i++) {
    mplew.writeInt(rs.getInt("localthreadid"));
    mplew.writeInt(rs.getInt("postercid"));
    mplew.writeMapleAsciiString(rs.getString("name"));
    mplew.writeLong(MaplePacketCreator.getKoreanTimestamp(rs.getLong("timestamp")));
    mplew.writeInt(rs.getInt("icon"));
    mplew.writeInt(rs.getInt("replycount"));
    rs.next();
    }
    return mplew.getPacket();
    }
    public static MaplePacket showThread(int localthreadid, ResultSet threadRS, ResultSet repliesRS) throws SQLException, RuntimeException {
    MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
    mplew.writeShort(SendPacketOpcode.BBS_OPERATION.getValue());
    mplew.write(0x07);
    mplew.writeInt(localthreadid);
    mplew.writeInt(threadRS.getInt("postercid"));
    mplew.writeLong(getKoreanTimestamp(threadRS.getLong("timestamp")));
    mplew.writeMapleAsciiString(threadRS.getString("name"));
    mplew.writeMapleAsciiString(threadRS.getString("startpost"));
    mplew.writeInt(threadRS.getInt("icon"));
    if (repliesRS != null) {
    int replyCount = threadRS.getInt("replycount");
    mplew.writeInt(replyCount);
    int i;
    for (i = 0; i < replyCount && repliesRS.next(); i++) {
    mplew.writeInt(repliesRS.getInt("replyid"));
    mplew.writeInt(repliesRS.getInt("postercid"));
    mplew.writeLong(getKoreanTimestamp(repliesRS.getLong("timestamp")));
    mplew.writeMapleAsciiString(repliesRS.getString("content"));
    }
    if (i != replyCount || repliesRS.next()) {
    //in the unlikely event that we lost count of replyid
    throw new RuntimeException(String.valueOf(threadRS.getInt("threadid")));
    //we need to fix the database and stop the packet sending
    //or else it'll probably error 38 whoever tries to read it
    //there is ONE case not checked, and that's when the thread
    //has a replycount of 0 and there is one or more replies to the
    //thread in bbs_replies
    }
    } else {
    mplew.writeInt(0); //0 replies
    }
    return mplew.getPacket();
    }

    -=

    didmz

    Posts : 8
    Join date : 2009-05-19

    Re: Guild BBS leak

    Post  didmz on Tue May 19, 2009 8:08 am

    thanks

    Sponsored content

    Re: Guild BBS leak

    Post  Sponsored content


      Current date/time is Sun Nov 18, 2018 4:02 pm