
-Removal of Q00344_1000YearsTheEndOfLamentation. -Fixed starting conditions for Q00144_PailakaInjuredDragon. -Fixed starting conditions for last Seven Sign quests. -Added missing MonasteryOfSilence.xml instance spawns and doors. -Removed many catacomb spawns.
617 lines
17 KiB
Java
617 lines
17 KiB
Java
/*
|
|
* Copyright (C) 2004-2015 L2J Server
|
|
*
|
|
* This file is part of L2J Server.
|
|
*
|
|
* L2J Server is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* L2J Server is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.l2jserver.gameserver.model.entity;
|
|
|
|
import static com.l2jserver.gameserver.model.itemcontainer.Inventory.ADENA_ID;
|
|
import static com.l2jserver.gameserver.model.itemcontainer.Inventory.MAX_ADENA;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.util.Calendar;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import com.l2jserver.L2DatabaseFactory;
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
|
|
import com.l2jserver.gameserver.enums.AuctionItemType;
|
|
import com.l2jserver.gameserver.idfactory.IdFactory;
|
|
import com.l2jserver.gameserver.instancemanager.ClanHallAuctionManager;
|
|
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
|
import com.l2jserver.gameserver.model.L2Clan;
|
|
import com.l2jserver.gameserver.model.L2World;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
import com.l2jserver.gameserver.network.SystemMessageId;
|
|
|
|
public class Auction
|
|
{
|
|
protected static final Logger _log = Logger.getLogger(Auction.class.getName());
|
|
private int _id = 0;
|
|
private long _endDate;
|
|
private int _highestBidderId = 0;
|
|
private String _highestBidderName = "";
|
|
private long _highestBidderMaxBid = 0;
|
|
private int _itemId = 0;
|
|
private String _itemName = "";
|
|
private int _itemObjectId = 0;
|
|
private final long _itemQuantity = 0;
|
|
private String _itemType = "";
|
|
private int _sellerId = 0;
|
|
private String _sellerClanName = "";
|
|
private String _sellerName = "";
|
|
private long _currentBid = 0;
|
|
private long _startingBid = 0;
|
|
|
|
private final Map<Integer, Bidder> _bidders = new HashMap<>();
|
|
|
|
private static final String[] ItemTypeName =
|
|
{
|
|
"ClanHall"
|
|
};
|
|
|
|
public static class Bidder
|
|
{
|
|
private final String _name; // TODO replace with objid
|
|
private final String _clanName;
|
|
private long _bid;
|
|
private final Calendar _timeBid;
|
|
|
|
public Bidder(String name, String clanName, long bid, long timeBid)
|
|
{
|
|
_name = name;
|
|
_clanName = clanName;
|
|
_bid = bid;
|
|
_timeBid = Calendar.getInstance();
|
|
_timeBid.setTimeInMillis(timeBid);
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return _name;
|
|
}
|
|
|
|
public String getClanName()
|
|
{
|
|
return _clanName;
|
|
}
|
|
|
|
public long getBid()
|
|
{
|
|
return _bid;
|
|
}
|
|
|
|
public Calendar getTimeBid()
|
|
{
|
|
return _timeBid;
|
|
}
|
|
|
|
public void setTimeBid(long timeBid)
|
|
{
|
|
_timeBid.setTimeInMillis(timeBid);
|
|
}
|
|
|
|
public void setBid(long bid)
|
|
{
|
|
_bid = bid;
|
|
}
|
|
}
|
|
|
|
/** Task Sheduler for endAuction */
|
|
public class AutoEndTask implements Runnable
|
|
{
|
|
public AutoEndTask()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void run()
|
|
{
|
|
try
|
|
{
|
|
endAuction();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
* @param auctionId
|
|
*/
|
|
public Auction(int auctionId)
|
|
{
|
|
_id = auctionId;
|
|
load();
|
|
startAutoTask();
|
|
}
|
|
|
|
public Auction(int itemId, L2Clan Clan, long delay, long bid, String name)
|
|
{
|
|
_id = itemId;
|
|
_endDate = System.currentTimeMillis() + delay;
|
|
_itemId = itemId;
|
|
_itemName = name;
|
|
_itemType = "ClanHall";
|
|
_sellerId = Clan.getLeaderId();
|
|
_sellerName = Clan.getLeaderName();
|
|
_sellerClanName = Clan.getName();
|
|
_startingBid = bid;
|
|
}
|
|
|
|
/** Load auctions */
|
|
private void load()
|
|
{
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("Select * from auction where id = ?"))
|
|
{
|
|
statement.setInt(1, getId());
|
|
try (ResultSet rs = statement.executeQuery())
|
|
{
|
|
while (rs.next())
|
|
{
|
|
_currentBid = rs.getLong("currentBid");
|
|
_endDate = rs.getLong("endDate");
|
|
_itemId = rs.getInt("itemId");
|
|
_itemName = rs.getString("itemName");
|
|
_itemObjectId = rs.getInt("itemObjectId");
|
|
_itemType = rs.getString("itemType");
|
|
_sellerId = rs.getInt("sellerId");
|
|
_sellerClanName = rs.getString("sellerClanName");
|
|
_sellerName = rs.getString("sellerName");
|
|
_startingBid = rs.getLong("startingBid");
|
|
}
|
|
}
|
|
loadBid();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.WARNING, "Exception: Auction.load(): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/** Load bidders **/
|
|
private void loadBid()
|
|
{
|
|
_highestBidderId = 0;
|
|
_highestBidderName = "";
|
|
_highestBidderMaxBid = 0;
|
|
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("SELECT bidderId, bidderName, maxBid, clan_name, time_bid FROM auction_bid WHERE auctionId = ? ORDER BY maxBid DESC"))
|
|
{
|
|
statement.setInt(1, getId());
|
|
try (ResultSet rs = statement.executeQuery())
|
|
{
|
|
while (rs.next())
|
|
{
|
|
if (rs.isFirst())
|
|
{
|
|
_highestBidderId = rs.getInt("bidderId");
|
|
_highestBidderName = rs.getString("bidderName");
|
|
_highestBidderMaxBid = rs.getLong("maxBid");
|
|
}
|
|
_bidders.put(rs.getInt("bidderId"), new Bidder(rs.getString("bidderName"), rs.getString("clan_name"), rs.getLong("maxBid"), rs.getLong("time_bid")));
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.WARNING, "Exception: Auction.loadBid(): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/** Task Manage */
|
|
private void startAutoTask()
|
|
{
|
|
long currentTime = System.currentTimeMillis();
|
|
long taskDelay = 0;
|
|
if (_endDate <= currentTime)
|
|
{
|
|
_endDate = currentTime + (7 * 24 * 3600000);
|
|
saveAuctionDate();
|
|
}
|
|
else
|
|
{
|
|
taskDelay = _endDate - currentTime;
|
|
}
|
|
ThreadPoolManager.getInstance().scheduleGeneral(new AutoEndTask(), taskDelay);
|
|
}
|
|
|
|
public static String getItemTypeName(AuctionItemType value)
|
|
{
|
|
return ItemTypeName[value.ordinal()];
|
|
}
|
|
|
|
/** Save Auction Data End */
|
|
private void saveAuctionDate()
|
|
{
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("Update auction set endDate = ? where id = ?"))
|
|
{
|
|
statement.setLong(1, _endDate);
|
|
statement.setInt(2, _id);
|
|
statement.execute();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: saveAuctionDate(): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a bid
|
|
* @param bidder
|
|
* @param bid
|
|
*/
|
|
public synchronized void setBid(L2PcInstance bidder, long bid)
|
|
{
|
|
long requiredAdena = bid;
|
|
if (getHighestBidderName().equals(bidder.getClan().getLeaderName()))
|
|
{
|
|
requiredAdena = bid - getHighestBidderMaxBid();
|
|
}
|
|
if (((getHighestBidderId() > 0) && (bid > getHighestBidderMaxBid())) || ((getHighestBidderId() == 0) && (bid >= getStartingBid())))
|
|
{
|
|
if (takeItem(bidder, requiredAdena))
|
|
{
|
|
updateInDB(bidder, bid);
|
|
bidder.getClan().setAuctionBiddedAt(_id, true);
|
|
return;
|
|
}
|
|
}
|
|
if ((bid < getStartingBid()) || (bid <= getHighestBidderMaxBid()))
|
|
{
|
|
bidder.sendPacket(SystemMessageId.YOUR_BID_PRICE_MUST_BE_HIGHER_THAN_THE_MINIMUM_PRICE_CURRENTLY_BEING_BID);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return Item in WHC
|
|
* @param Clan
|
|
* @param quantity
|
|
* @param penalty
|
|
*/
|
|
private void returnItem(String Clan, long quantity, boolean penalty)
|
|
{
|
|
if (penalty)
|
|
{
|
|
quantity *= 0.9; // take 10% tax fee if needed
|
|
}
|
|
|
|
// avoid overflow on return
|
|
final long limit = MAX_ADENA - ClanTable.getInstance().getClanByName(Clan).getWarehouse().getAdena();
|
|
quantity = Math.min(quantity, limit);
|
|
|
|
ClanTable.getInstance().getClanByName(Clan).getWarehouse().addItem("Outbidded", ADENA_ID, quantity, null, null);
|
|
}
|
|
|
|
/**
|
|
* Take Item in WHC
|
|
* @param bidder
|
|
* @param quantity
|
|
* @return
|
|
*/
|
|
private boolean takeItem(L2PcInstance bidder, long quantity)
|
|
{
|
|
if ((bidder.getClan() != null) && (bidder.getClan().getWarehouse().getAdena() >= quantity))
|
|
{
|
|
bidder.getClan().getWarehouse().destroyItemByItemId("Buy", ADENA_ID, quantity, bidder, bidder);
|
|
return true;
|
|
}
|
|
bidder.sendPacket(SystemMessageId.THERE_IS_NOT_ENOUGH_ADENA_IN_THE_CLAN_HALL_WAREHOUSE);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Update auction in DB
|
|
* @param bidder
|
|
* @param bid
|
|
*/
|
|
private void updateInDB(L2PcInstance bidder, long bid)
|
|
{
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
|
{
|
|
if (getBidders().get(bidder.getClanId()) != null)
|
|
{
|
|
try (PreparedStatement statement = con.prepareStatement("UPDATE auction_bid SET bidderId=?, bidderName=?, maxBid=?, time_bid=? WHERE auctionId=? AND bidderId=?"))
|
|
{
|
|
statement.setInt(1, bidder.getClanId());
|
|
statement.setString(2, bidder.getClan().getLeaderName());
|
|
statement.setLong(3, bid);
|
|
statement.setLong(4, System.currentTimeMillis());
|
|
statement.setInt(5, getId());
|
|
statement.setInt(6, bidder.getClanId());
|
|
statement.execute();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try (PreparedStatement statement = con.prepareStatement("INSERT INTO auction_bid (id, auctionId, bidderId, bidderName, maxBid, clan_name, time_bid) VALUES (?, ?, ?, ?, ?, ?, ?)"))
|
|
{
|
|
statement.setInt(1, IdFactory.getInstance().getNextId());
|
|
statement.setInt(2, getId());
|
|
statement.setInt(3, bidder.getClanId());
|
|
statement.setString(4, bidder.getName());
|
|
statement.setLong(5, bid);
|
|
statement.setString(6, bidder.getClan().getName());
|
|
statement.setLong(7, System.currentTimeMillis());
|
|
statement.execute();
|
|
}
|
|
if (L2World.getInstance().getPlayer(_highestBidderName) != null)
|
|
{
|
|
L2World.getInstance().getPlayer(_highestBidderName).sendMessage("You have been out bidded");
|
|
}
|
|
}
|
|
|
|
_highestBidderId = bidder.getClanId();
|
|
_highestBidderMaxBid = bid;
|
|
_highestBidderName = bidder.getClan().getLeaderName();
|
|
if (_bidders.get(_highestBidderId) == null)
|
|
{
|
|
_bidders.put(_highestBidderId, new Bidder(_highestBidderName, bidder.getClan().getName(), bid, Calendar.getInstance().getTimeInMillis()));
|
|
}
|
|
else
|
|
{
|
|
_bidders.get(_highestBidderId).setBid(bid);
|
|
_bidders.get(_highestBidderId).setTimeBid(Calendar.getInstance().getTimeInMillis());
|
|
}
|
|
bidder.sendPacket(SystemMessageId.YOUR_BID_HAS_BEEN_SUCCESSFULLY_PLACED);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: Auction.updateInDB(L2PcInstance bidder, int bid): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/** Remove bids */
|
|
private void removeBids()
|
|
{
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("DELETE FROM auction_bid WHERE auctionId=?"))
|
|
{
|
|
statement.setInt(1, getId());
|
|
statement.execute();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: Auction.deleteFromDB(): " + e.getMessage(), e);
|
|
}
|
|
|
|
for (Bidder b : _bidders.values())
|
|
{
|
|
if (ClanTable.getInstance().getClanByName(b.getClanName()).getHideoutId() == 0)
|
|
{
|
|
returnItem(b.getClanName(), b.getBid(), true); // 10 % tax
|
|
}
|
|
else
|
|
{
|
|
if (L2World.getInstance().getPlayer(b.getName()) != null)
|
|
{
|
|
L2World.getInstance().getPlayer(b.getName()).sendMessage("Congratulation you have won ClanHall!");
|
|
}
|
|
}
|
|
ClanTable.getInstance().getClanByName(b.getClanName()).setAuctionBiddedAt(0, true);
|
|
}
|
|
_bidders.clear();
|
|
}
|
|
|
|
/** Remove auctions */
|
|
public void deleteAuctionFromDB()
|
|
{
|
|
ClanHallAuctionManager.getInstance().getAuctions().remove(this);
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("DELETE FROM auction WHERE itemId=?"))
|
|
{
|
|
statement.setInt(1, _itemId);
|
|
statement.execute();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: Auction.deleteFromDB(): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/** End of auction */
|
|
public void endAuction()
|
|
{
|
|
if (ClanHallManager.getInstance().loaded())
|
|
{
|
|
if ((_highestBidderId == 0) && (_sellerId == 0))
|
|
{
|
|
startAutoTask();
|
|
return;
|
|
}
|
|
if ((_highestBidderId == 0) && (_sellerId > 0))
|
|
{
|
|
/**
|
|
* If seller haven't sell ClanHall, auction removed, THIS MUST BE CONFIRMED
|
|
*/
|
|
int aucId = ClanHallAuctionManager.getInstance().getAuctionIndex(_id);
|
|
ClanHallAuctionManager.getInstance().getAuctions().remove(aucId);
|
|
return;
|
|
}
|
|
if (_sellerId > 0)
|
|
{
|
|
returnItem(_sellerClanName, _highestBidderMaxBid, true);
|
|
returnItem(_sellerClanName, ClanHallManager.getInstance().getAuctionableHallById(_itemId).getLease(), false);
|
|
}
|
|
deleteAuctionFromDB();
|
|
L2Clan Clan = ClanTable.getInstance().getClanByName(_bidders.get(_highestBidderId).getClanName());
|
|
_bidders.remove(_highestBidderId);
|
|
Clan.setAuctionBiddedAt(0, true);
|
|
removeBids();
|
|
ClanHallManager.getInstance().setOwner(_itemId, Clan);
|
|
}
|
|
else
|
|
{
|
|
/** Task waiting ClanHallManager is loaded every 3s */
|
|
ThreadPoolManager.getInstance().scheduleGeneral(new AutoEndTask(), 3000);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cancel bid
|
|
* @param bidder
|
|
*/
|
|
public synchronized void cancelBid(int bidder)
|
|
{
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("DELETE FROM auction_bid WHERE auctionId=? AND bidderId=?"))
|
|
{
|
|
statement.setInt(1, getId());
|
|
statement.setInt(2, bidder);
|
|
statement.execute();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: Auction.cancelBid(String bidder): " + e.getMessage(), e);
|
|
}
|
|
|
|
returnItem(_bidders.get(bidder).getClanName(), _bidders.get(bidder).getBid(), true);
|
|
ClanTable.getInstance().getClanByName(_bidders.get(bidder).getClanName()).setAuctionBiddedAt(0, true);
|
|
_bidders.clear();
|
|
loadBid();
|
|
}
|
|
|
|
/** Cancel auction */
|
|
public void cancelAuction()
|
|
{
|
|
deleteAuctionFromDB();
|
|
removeBids();
|
|
}
|
|
|
|
/** Confirm an auction */
|
|
public void confirmAuction()
|
|
{
|
|
ClanHallAuctionManager.getInstance().getAuctions().add(this);
|
|
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
|
PreparedStatement statement = con.prepareStatement("INSERT INTO auction (id, sellerId, sellerName, sellerClanName, itemType, itemId, itemObjectId, itemName, itemQuantity, startingBid, currentBid, endDate) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"))
|
|
{
|
|
statement.setInt(1, getId());
|
|
statement.setInt(2, _sellerId);
|
|
statement.setString(3, _sellerName);
|
|
statement.setString(4, _sellerClanName);
|
|
statement.setString(5, _itemType);
|
|
statement.setInt(6, _itemId);
|
|
statement.setInt(7, _itemObjectId);
|
|
statement.setString(8, _itemName);
|
|
statement.setLong(9, _itemQuantity);
|
|
statement.setLong(10, _startingBid);
|
|
statement.setLong(11, _currentBid);
|
|
statement.setLong(12, _endDate);
|
|
statement.execute();
|
|
statement.close();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_log.log(Level.SEVERE, "Exception: Auction.load(): " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get var auction
|
|
* @return
|
|
*/
|
|
public final int getId()
|
|
{
|
|
return _id;
|
|
}
|
|
|
|
public final long getCurrentBid()
|
|
{
|
|
return _currentBid;
|
|
}
|
|
|
|
public final long getEndDate()
|
|
{
|
|
return _endDate;
|
|
}
|
|
|
|
public final int getHighestBidderId()
|
|
{
|
|
return _highestBidderId;
|
|
}
|
|
|
|
public final String getHighestBidderName()
|
|
{
|
|
return _highestBidderName;
|
|
}
|
|
|
|
public final long getHighestBidderMaxBid()
|
|
{
|
|
return _highestBidderMaxBid;
|
|
}
|
|
|
|
public final int getItemId()
|
|
{
|
|
return _itemId;
|
|
}
|
|
|
|
public final String getItemName()
|
|
{
|
|
return _itemName;
|
|
}
|
|
|
|
public final int getItemObjectId()
|
|
{
|
|
return _itemObjectId;
|
|
}
|
|
|
|
public final long getItemQuantity()
|
|
{
|
|
return _itemQuantity;
|
|
}
|
|
|
|
public final String getItemType()
|
|
{
|
|
return _itemType;
|
|
}
|
|
|
|
public final int getSellerId()
|
|
{
|
|
return _sellerId;
|
|
}
|
|
|
|
public final String getSellerName()
|
|
{
|
|
return _sellerName;
|
|
}
|
|
|
|
public final String getSellerClanName()
|
|
{
|
|
return _sellerClanName;
|
|
}
|
|
|
|
public final long getStartingBid()
|
|
{
|
|
return _startingBid;
|
|
}
|
|
|
|
public final Map<Integer, Bidder> getBidders()
|
|
{
|
|
return _bidders;
|
|
}
|
|
}
|