Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Куплю исправление ошибки
#1
При запуске гейм сервера возникает такая ошибка

PHP код:
<?php 
15
:46:02.543 Clear characters online status and accesslevel.
15:46:02.916 Total cleaned: 0, updated: 0 elements in database.
java.lang.Exception: IdFactory: there are duplicates in object ids
at l2p
.gameserver.idfactory.IdFactory.extractUsedObjectIDTable1(IdFactory.java:117)
at l2p.gameserver.idfactory.IdFactory.extractUsedObjectIDTable(IdFactory.java:93)
at l2p.gameserver.idfactory.BitSetIDFactory.initialize(BitSetIDFactory.java:43)
at l2p.gameserver.idfactory.BitSetIDFactory.<init>(BitSetIDFactory.java:32)
at l2p.gameserver.idfactory.IdFactory.<clinit>(IdFactory.java:24)
at l2p.gameserver.GameServer.<init>(GameServer.java:135)
at l2p.gameserver.GameServer.main(GameServer.java:436)
Server exiting [status=0] / Reason: IdFactory

Сборка работает на исходниках L2Phoenix.

IdFactory.java

PHP код:
<?php 
package l2p
.gameserver.idfactory;

import l2p.Config;
import l2p.Server;
import l2p.common.ParallelExecutor;
import l2p.database.DatabaseUtils;
import l2p.database.FiltredStatement;
import l2p.database.L2DatabaseFactory;
import l2p.database.ThreadConnection;
import l2p.gameserver.idfactory.Tasks.ClearQuery;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;

public abstract class
IdFactory
{
private static
Logger _log = Logger.getLogger(IdFactory.class.getName());
protected
boolean initialized;
protected
long releasedCount = 0;
public static final
int FIRST_OID = 0x10000000;
public static final
int LAST_OID = 0x7FFFFFFF;
public static final
int FREE_OBJECT_ID_SIZE = LAST_OID - FIRST_OID;
protected static final
IdFactory _instance = new BitSetIDFactory();

protected
IdFactory()
{
setAllCharacterOffline();
if(
Config.MULTI_THREADED_IDFACTORY_CLEANER)
{
mt_cleanUpDB();
}
else
{
cleanUpDB();
}
}

private
void setAllCharacterOffline()
{
ThreadConnection conn = null;
FiltredStatement stmt = null;
try
{
conn = L2DatabaseFactory.getInstance().getConnection();
stmt = conn.createStatement();
stmt.executeUpdate("UPDATE characters SET online = 0");
stmt.executeUpdate("UPDATE characters SET accesslevel = 0 WHERE accesslevel = -1");
_log.info("Clear characters online status and accesslevel.");
}
catch(
SQLException e)
{
}
finally
{
DatabaseUtils.closeDatabaseCS(conn, stmt);
}
}

/**
* Cleans up Database
*/
private void cleanUpDB()
{
for(
ClearQuery q : ClearQuery.values())
{
q.run();
}
_log.info("Total cleaned: " + ClearQuery.totalDeleted + ", updated: " + ClearQuery.totalUpdated + " elements in database.");
}

private
void mt_cleanUpDB()
{
ParallelExecutor executor = new ParallelExecutor("cleanUpDB", Thread.NORM_PRIORITY, ClearQuery.values().length);
try
{
for(
ClearQuery q : ClearQuery.values())
{
executor.execute(q);
}
executor.waitForFinishAndDestroy();
_log.info("Total cleaned: " + ClearQuery.totalDeleted + ", updated: " + ClearQuery.totalUpdated + " elements in database.");
}
catch(
InterruptedException e)
{
e.printStackTrace();
Server.exit(0, "cleanUpDB");
}
}

protected
int[] extractUsedObjectIDTable()
{
return
Config.MULTI_THREADED_IDFACTORY_EXTRACTOR ? extractUsedObjectIDTable2() : extractUsedObjectIDTable1();
}

protected
int[] extractUsedObjectIDTable1()
{
ThreadConnection con = null;
FiltredStatement s = null;
ResultSet rs = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
s = con.createStatement();
String query = "SELECT " + Tasks.objTables[0][1] + ", 0 AS i FROM " + Tasks.objTables[0][0];
for(
int i = 1; i < Tasks.objTables.length; i++)
{
query += " UNION SELECT " + Tasks.objTables[i][1] + ", " + i + " FROM " + Tasks.objTables[i][0];
}
rs = s.executeQuery("SELECT COUNT(*), COUNT(DISTINCT " + Tasks.objTables[0][1] + ") FROM ( " + query + " ) AS all_ids");
if(!
rs.next())
{
throw new
Exception("IdFactory: can't extract count ids");
}
if(
rs.getInt(1) != rs.getInt(2))
{
throw new
Exception("IdFactory: there are duplicates in object ids");
}
int[] result = new int[rs.getInt(1)];
DatabaseUtils.closeResultSet(rs);
_log.info("IdFactory: Extracting " + result.length + " used id's from data tables...");
rs = s.executeQuery(query);
int idx = 0;
while(
rs.next())
{
result[idx++] = rs.getInt(1);
}
_log.info("IdFactory: Successfully extracted " + idx + " used id's from data tables.");
return
result;
}
catch(
Exception e)
{
e.printStackTrace();
Server.exit(0, "IdFactory");
return
null;
}
finally
{
DatabaseUtils.closeDatabaseCSR(con, s, rs);
}
}

protected
int[] extractUsedObjectIDTable2()
{
// считаем количество по всем таблицам распаралеленно
final int[][] objCounts = new int[Tasks.objTables.length][];
ParallelExecutor multiextractor = new ParallelExecutor("extractUsedObjectIDTable::CountObjectIds", Thread.NORM_PRIORITY, Tasks.objTables.length);
try
{
for(
int i = 0; i < Tasks.objTables.length; i++)
{
objCounts[i] = new int[2];
multiextractor.execute(new Tasks.CountObjectIds(Tasks.objTables[i], objCounts[i]));
}
multiextractor.waitForFinishAndDestroy();
}
catch(
InterruptedException e)
{
e.printStackTrace();
Server.exit(0, "IdFactory::CountObjectIds");
}
// выставляем смещения для каждой таблици
int idx = 0;
for(
int i = 0; i < objCounts.length; i++)
{
objCounts[i][1] = idx;
idx += objCounts[i][0];
}
int[] result = new int[idx];
_log.info("IdFactory: Extracting " + result.length + " used id's from data tables...");
// извлекаем идентификаторы по всем таблицам распаралеленно
multiextractor = new ParallelExecutor("extractUsedObjectIDTable::ExtractObjectIds", Thread.NORM_PRIORITY, Tasks.objTables.length);
try
{
for(
int i = 0; i < Tasks.objTables.length; i++)
{
multiextractor.execute(new Tasks.ExtractObjectIds(Tasks.objTables[i], objCounts[i], result));
}
multiextractor.waitForFinishAndDestroy();
}
catch(
InterruptedException e)
{
e.printStackTrace();
Server.exit(0, "IdFactory::ExtractObjectIds");
}
_log.info("IdFactory: Successfully extracted " + result.length + " used id's from data tables.");
return
result;
}

public
boolean isInitialized()
{
return
initialized;
}

public static
IdFactory getInstance()
{
return
_instance;
}

public abstract
int getNextId();

/**
* return a used Object ID back to the pool
*
* @param object ID
*/
public void releaseId(int id)
{
releasedCount++;
}

public
long getReleasedCount()
{
return
releasedCount;
}

public abstract
int size();

public static
void unload()
{
if(
_instance != null)
{
((
BitSetIDFactory) _instance)._unload();
}
}
}

BitSetIDFactory.java

PHP код:
<?php 
package l2p
.gameserver.idfactory;

import l2p.common.ThreadPoolManager;
import l2p.util.PrimeFinder;

import java.util.BitSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class
BitSetIDFactory extends IdFactory
{
private static
Logger _log = Logger.getLogger(BitSetIDFactory.class.getName());
private
BitSet freeIds;
private
AtomicInteger freeIdCount;
private
AtomicInteger nextFreeId;

public class
BitSetCapacityCheck implements Runnable
{
public
void run()
{
if(
reachingBitSetCapacity())
{
increaseBitSetCapacity();
}
}
}

protected
BitSetIDFactory()
{
super();
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new BitSetCapacityCheck(), 30000, 30000);
initialize();
_log.info("IDFactory: " + freeIds.size() + " id's available.");
}

public
synchronized void initialize()
{
try
{
freeIds = new BitSet(PrimeFinder.nextPrime(100000));
freeIds.clear();
freeIdCount = new AtomicInteger(FREE_OBJECT_ID_SIZE);
for(
int usedObjectId : extractUsedObjectIDTable())
{
int objectID = usedObjectId - FIRST_OID;
if(
objectID < 0)
{
_log.warning("Object ID " + usedObjectId + " in DB is less than minimum ID of " + FIRST_OID);
continue;
}
freeIds.set(usedObjectId - FIRST_OID);
freeIdCount.decrementAndGet();
}
nextFreeId = new AtomicInteger(freeIds.nextClearBit(0));
initialized = true;
}
catch(
Exception e)
{
initialized = false;
_log.severe("BitSet ID Factory could not be initialized correctly");
e.printStackTrace();
}
}

@
Override
public synchronized void releaseId(int objectID)
{
if(
objectID - FIRST_OID > -1)
{
freeIds.clear(objectID - FIRST_OID);
freeIdCount.incrementAndGet();
super.releaseId(objectID);
}
else
{
_log.warning("BitSet ID Factory: release objectID " + objectID + " failed (< " + FIRST_OID + ")");
}
}

@
Override
public synchronized int getNextId()
{
int newID = nextFreeId.get();
freeIds.set(newID);
freeIdCount.decrementAndGet();
int nextFree = freeIds.nextClearBit(newID);
if(
nextFree < 0)
{
nextFree = freeIds.nextClearBit(0);
}
if(
nextFree < 0)
{
if(
freeIds.size() < FREE_OBJECT_ID_SIZE)
{
increaseBitSetCapacity();
}
else
{
throw new
NullPointerException("Ran out of valid Id's.");
}
}
nextFreeId.set(nextFree);
return
newID + FIRST_OID;
}

@
Override
public synchronized int size()
{
return
freeIdCount.get();
}

protected
synchronized int usedIdCount()
{
return
size() - FIRST_OID;
}

protected
synchronized boolean reachingBitSetCapacity()
{
return
PrimeFinder.nextPrime(usedIdCount() * 11 / 10) > freeIds.size();
}

protected
synchronized void increaseBitSetCapacity()
{
BitSet newBitSet = new BitSet(PrimeFinder.nextPrime(usedIdCount() * 11 / 10));
newBitSet.or(freeIds);
freeIds = newBitSet;
}

public
void _unload()
{
freeIds.clear();
freeIds = null;
}
}
Ответ
#2
Я извиняюсь конечно, но гейм сервер вам сообщает

dFactory: there are duplicates in object ids

что означает что в БД сервера есть Два или более одинаковых object id. Поищите. В базе не может быть одинаков айди у предметов/чаров/кланов и так далее. Каждая такая запись должна быть уникальна. Видимо был сбой на сервере и в базу попал мусор.

...И не нужен никакой ява код.
Ответ
#3
было дело я когда портировал с indev сборки(про целостность данных они не слышали) на фена такиеже косяки встречал, правил sql запросом, уже не помню каким
Ответ
#4
repaire table_name;
Ответ
#5
ReaM Написал:repaire table_name;

там нет праймари кеев, это не поможет
Ответ
#6
Для удаления дубликатов записей можно использовать следующие команды:
table_name - заменить на название таблицы
unique_key - заменить на поле в котором, после выполнения запроса, не останется дубликатов.
ID - уникальный ключ в таблице.

DELETE tn FROM table_name tn JOIN (SELECT MAX(ID) AS ID FROM TABLE_NAME GROUP BY unique_key HAVING COUNT(*) > 1) tn2 USING(ID)

Если нет праймари кея, на время выполнения запроса создай его исскуственно тому полю, по которому у тебя идет конфликт (obj_id насколько понял)

Вообще такая проблема возникала пару раз, когда при падении сервера вещи на земле при поднятии сохранялись и в инвентарь игроку и в временную таблицу items_on_ground.
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Куплю аккаунты unitpay DailyFrost 7 3,046 10-13-2020, 03:51 PM
Последний пост: Piroman
  Куплю серверные файлы villabox 0 1,743 09-13-2019, 01:20 AM
Последний пост: villabox
  Куплю базу e-mail адресов Laguerro 0 1,054 02-03-2019, 12:51 AM
Последний пост: Laguerro
  Куплю шаблоны для редактора клиента L2 152 протокол Visor 0 1,346 01-09-2019, 08:52 PM
Последний пост: Visor
  Куплю лицензию Advext Ivanushka 0 1,315 08-09-2018, 10:32 PM
Последний пост: Ivanushka
  Куплю готовое приложение или разработку + разовая или постоянная работа для кодеров JeronimoScarzesse 0 1,603 07-13-2018, 03:59 PM
Последний пост: JeronimoScarzesse
  Куплю базы la2 номеров с платежных систем Laguerro 1 1,720 06-07-2018, 02:47 PM
Последний пост: Vavilon
  Куплю движок анонсера DailyFrost 2 1,930 05-14-2018, 03:23 PM
Последний пост: tCode
  Куплю UE vesovoi 1 1,706 04-27-2018, 08:55 PM
Последний пост: DmnC
  Куплю сурс Grand Crusade KillMozg 6 2,625 11-03-2017, 04:06 PM
Последний пост: Shell

Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)