Merge pull request #68 from P0nk/saving-monsterbook

Improve monsterbook saving
This commit is contained in:
Ponk
2022-01-19 18:06:48 +01:00
committed by GitHub
4 changed files with 29 additions and 58 deletions

View File

@@ -15978,9 +15978,11 @@ CREATE TABLE IF NOT EXISTS `medalmaps` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `monsterbook` (
`charid` int(11) unsigned NOT NULL,
`charid` int(11) NOT NULL,
`cardid` int(11) NOT NULL,
`level` int(1) DEFAULT '1'
`level` int(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`charid`, `cardid`),
CONSTRAINT `FK_monsterbook_characters` FOREIGN KEY (`charid`) REFERENCES `characters`(`id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `monstercarddata` (

View File

@@ -0,0 +1,6 @@
/* Manually run this script in MySQL Workbench or some other database client
to migrate your old (pre Jan 19th 2022) monsterbook table to the new version */
ALTER TABLE cosmic.`monsterbook`
CHANGE COLUMN `charid` `charid` INT(11) NOT NULL,
ADD PRIMARY KEY (`charid`, `cardid`),
ADD CONSTRAINT `FK_monsterbook_1` FOREIGN KEY (`charid`) REFERENCES `characters` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;

View File

@@ -8464,7 +8464,7 @@ public class Character extends AbstractCharacterObject {
ps.setInt(i + 31, getSlots(i));
}
monsterbook.saveCards(getId());
monsterbook.saveCards(con, id);
ps.setInt(36, bookCover);
ps.setInt(37, vanquisherStage);

View File

@@ -32,12 +32,9 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
public final class MonsterBook {
private static final Semaphore semaphore = new Semaphore(10);
private int specialCard = 0;
private int normalCard = 0;
private int bookLevel = 1;
@@ -180,61 +177,27 @@ public final class MonsterBook {
calculateLevel();
}
private static int saveStringConcat(char[] data, int pos, Integer i) {
return saveStringConcat(data, pos, i.toString());
}
public void saveCards(Connection con, int chrId) throws SQLException {
final String query = """
INSERT INTO monsterbook (charid, cardid, level)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE level = ?;
""";
try (final PreparedStatement ps = con.prepareStatement(query)) {
for (Map.Entry<Integer, Integer> cardAndLevel : cards.entrySet()) {
final int card = cardAndLevel.getKey();
final int level = cardAndLevel.getValue();
// insert
ps.setInt(1, chrId);
ps.setInt(2, card);
ps.setInt(3, level);
private static int saveStringConcat(char[] data, int pos, String s) {
int len = s.length();
for (int j = 0; j < len; j++) {
data[pos + j] = s.charAt(j);
}
// update
ps.setInt(4, level);
return pos + len;
}
private static String getSaveString(Integer charid, Set<Entry<Integer, Integer>> cardSet) {
semaphore.acquireUninterruptibly();
try {
char[] save = new char[400000]; // 500 * 10 * 10 * 8
int i = 0;
i = saveStringConcat(save, i, "INSERT INTO monsterbook VALUES ");
for (Entry<Integer, Integer> all : cardSet) { // assuming maxsize 500 unique cards
i = saveStringConcat(save, i, "(");
i = saveStringConcat(save, i, charid); //10 chars
i = saveStringConcat(save, i, ", ");
i = saveStringConcat(save, i, all.getKey()); //10 chars
i = saveStringConcat(save, i, ", ");
i = saveStringConcat(save, i, all.getValue()); //1 char due to being 0 ~ 5
i = saveStringConcat(save, i, "),");
ps.addBatch();
}
return new String(save, 0, i - 1);
} finally {
semaphore.release();
}
}
public void saveCards(final int charid) {
Set<Entry<Integer, Integer>> cardSet = getCardSet();
if (cardSet.isEmpty()) {
return;
}
try (Connection con = DatabaseConnection.getConnection()) {
try (PreparedStatement ps = con.prepareStatement("DELETE FROM monsterbook WHERE charid = ?")) {
ps.setInt(1, charid);
ps.executeUpdate();
}
try (PreparedStatement ps = con.prepareStatement(getSaveString(charid, cardSet))) {
ps.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
ps.executeBatch();
}
}