Здравствуйте, уважаемые.
В некоторых своих статьях и советах упомянаю "пользовательские переменные" - способ сохранять некую информацию и настройки без рефакторинга всего кода и базы.
Я, к примеру, храню в них индивидуальные настройки автолутов, режим экономии трафика, отображение достижений, отображение торговцев, и прочие настройки, которые игрок выбирает сам.
Так же храню в них имя супруги/супруга, если персонажи поженились. Есть такая необходимость, и это лучше, чем грузить из базы, если партнер не в сети...
При входе игрока производится загрузка мапов всех переменных в память, при выходи и периодически - сохранение.
При изменении/добавлении/удалении переменной обновлять базу не рекомендую - может использоваться как ДДОС и привести к перегрузкам.
Сразу оговорюсь: Если у Вас сборка не на исходниках L2J - придется допиливать самостоятельно, либо покупать (или клянчить у других) адаптацию.
Итак, поехали.
Будем править только один класс - L2PcInstance.
Для начала в самый конец класса добавим объявления и методы:
private Map<String, String> _vars = new FastMap<String, String>();
//-----------------------------------------------------------------
public void setVar(String vName, String vValue){
_vars.put(vName, vValue);
}
public void setBoolVar(String vName, boolean vValue){
if (vValue) _vars.put(vName, "true");
else _vars.put(vName, "false");
}
//-----------------------------------------------------------------
public String getVar(String vName){
String tmpVal = _vars.get(vName);
return tmpVal != null ? tmpVal : "";
}
public boolean getBoolVar(String vName){
String tmpVal = _vars.get(vName);
return (tmpVal == null || tmpVal.equals("false")) ? false : true;
}
//-----------------------------------------------------------------
public final void delVar(String vName){
_vars.remove(vName);
}
//-----------------------------------------------------------------
private final void StoreVars(){
Connection con = null;
try{
con = L2DatabaseFactory.getInstance().getConnection();
con.prepareStatement("DELETE FROM `character_variables` WHERE `OID`="+getObjectId()).executeUpdate();
if (_vars.size() > 0){
PreparedStatement statement = con.prepareStatement("INSERT INTO `character_variables` (`OID`, `VarName`, `VarValue`) VALUES (?,?,?)");
for (final String key : _vars.keySet()){
final String value = _vars.get(key);
statement.setInt(1, getObjectId());
statement.setString(2, key);
statement.setString(3, value);
statement.executeUpdate();
statement.clearParameters();
}
statement.close();
}
}
catch (Exception e) {_log.log(Level.WARNING, "", e);}
finally {L2DatabaseFactory.close(con);}
}
private final void RestoreVars(){
Connection con = null;
try{
con = L2DatabaseFactory.getInstance().getConnection();
ResultSet vars = con.prepareStatement("SELECT * FROM character_variables WHERE OID="+getObjectId()).executeQuery();
while (vars.next()){
_vars.put(vars.getString("VarName"),vars.getString("VarValue"));
}
vars.close();
}
catch (Exception e) {_log.log(Level.WARNING, "", e);}
finally {L2DatabaseFactory.close(con);}
}
После этих строк должен остаться только один символ - } - закрывающий весь класс.
Дальше. Ищем метод загрузки: private static L2PcInstance restore(int objectId)
Почти в самы конец метода, перед кетчами, вызываем наш метод загрузки:
player.restoreZoneRestartLimitTime();
player.RestoreVars();
}
catch (Exception e) {_log.log(Level.SEVERE, "Failed loading character.", e);}
Метод должен быть вызван именно последним в загрузках. Почему - думайте сами.
Далее. Ищем метод: public void store()
Опять же, в самый конец метода добавляем наш метод сохранения:
SevenSigns.getInstance().saveSevenSignsData(getObjectId());
StoreVars();
}
С кодом покончено, осталось создать таблицу в базе.
В Навикате/ПхпМайАдмине/другой_проге_СУБД исполняем запрос для своей базы:
DROP TABLE IF EXISTS `character_variables`;
CREATE TABLE `character_variables` (
`OID` int(11) NOT NULL DEFAULT '0',
`VarName` varchar(50) NOT NULL DEFAULT '0',
`VarValue` varchar(255) NOT NULL DEFAULT '0',
UNIQUE KEY `prim` (`OID`,`VarName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Собсна, всё.
Использование простейшее:
player.setVar("myoption","qwerty");
String _var = player.getVar("myoption");
player.delVar("myoption");
Соответственно:
Создаст или изменит переменную.
Получит значение переменной (даже после рестарта сервера, для этого и делали).
Удалит переменную (после релогина/рестарта - удалит и из базы).
Если кому-то из модеров так претит неоформленный текст - правьте сами, не мне это надо.
Если копируете мануал - будьте добры оставлять ссылку на Автора, или на топик формума с первоисточником мануала.