2011-12-08 05:44:18 +01:00
package com.earth2me.essentials ;
2013-05-06 07:40:22 +02:00
import com.earth2me.essentials.Trade.OverflowType ;
2011-12-08 05:44:18 +01:00
import com.earth2me.essentials.commands.NoChargeException ;
2022-12-24 18:58:51 +01:00
import com.earth2me.essentials.craftbukkit.Inventories ;
2013-04-29 13:31:08 +02:00
import com.earth2me.essentials.textreader.IText ;
import com.earth2me.essentials.textreader.KeywordReplacer ;
import com.earth2me.essentials.textreader.SimpleTextInput ;
2024-02-04 03:13:18 +01:00
import com.earth2me.essentials.utils.AdventureUtil ;
2013-06-08 23:31:19 +02:00
import com.earth2me.essentials.utils.DateUtil ;
2020-05-11 16:20:00 +02:00
import com.earth2me.essentials.utils.NumberUtil ;
2013-10-11 04:44:41 +02:00
import net.ess3.api.IEssentials ;
2024-02-03 21:38:14 +01:00
import net.ess3.api.TranslatableException ;
2020-05-09 22:19:51 +02:00
import net.ess3.api.events.KitClaimEvent ;
2023-07-01 23:51:58 +02:00
import net.essentialsx.api.v2.events.KitPreExpandItemsEvent ;
2015-04-17 21:48:23 +02:00
import org.bukkit.Bukkit ;
2013-09-17 13:29:03 +02:00
import org.bukkit.Material ;
2011-12-08 05:44:18 +01:00
import org.bukkit.inventory.ItemStack ;
2021-06-26 22:03:27 +02:00
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder ;
2011-12-08 05:44:18 +01:00
2015-04-15 06:06:16 +02:00
import java.math.BigDecimal ;
2020-10-03 19:46:05 +02:00
import java.util.ArrayList ;
2022-12-24 18:58:51 +01:00
import java.util.Arrays ;
2020-10-03 19:46:05 +02:00
import java.util.Calendar ;
import java.util.GregorianCalendar ;
import java.util.List ;
import java.util.Map ;
2015-04-15 06:06:16 +02:00
import java.util.logging.Level ;
2024-02-03 21:38:14 +01:00
import static com.earth2me.essentials.I18n.tlLiteral ;
2015-04-15 06:06:16 +02:00
public class Kit {
final IEssentials ess ;
final String kitName ;
final Map < String , Object > kit ;
final Trade charge ;
public Kit ( final String kitName , final IEssentials ess ) throws Exception {
this . kitName = kitName ;
this . ess = ess ;
2018-01-18 09:25:00 +01:00
this . kit = ess . getKits ( ) . getKit ( kitName ) ;
2015-04-15 06:06:16 +02:00
this . charge = new Trade ( " kit- " + kitName , new Trade ( " kit-kit " , ess ) , ess ) ;
if ( kit = = null ) {
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( " kitNotFound " ) ;
2015-04-15 06:06:16 +02:00
}
}
public String getName ( ) {
return kitName ;
}
public void checkPerms ( final User user ) throws Exception {
if ( ! user . isAuthorized ( " essentials.kits. " + kitName ) ) {
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( " noKitPermission " , " essentials.kits. " + kitName ) ;
2015-04-15 06:06:16 +02:00
}
}
public void checkDelay ( final User user ) throws Exception {
2020-10-03 19:46:05 +02:00
final long nextUse = getNextUse ( user ) ;
2015-04-15 06:06:16 +02:00
if ( nextUse = = 0L ) {
} else if ( nextUse < 0L ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " kitOnce " ) ;
2015-04-15 06:06:16 +02:00
throw new NoChargeException ( ) ;
} else {
2024-02-03 21:38:14 +01:00
user . sendTl ( " kitTimed " , DateUtil . formatDateDiff ( nextUse ) ) ;
2015-04-15 06:06:16 +02:00
throw new NoChargeException ( ) ;
}
}
public void checkAffordable ( final User user ) throws Exception {
charge . isAffordableFor ( user ) ;
}
public void setTime ( final User user ) throws Exception {
final Calendar time = new GregorianCalendar ( ) ;
user . setKitTimestamp ( kitName , time . getTimeInMillis ( ) ) ;
}
2021-02-05 20:35:38 +01:00
public void resetTime ( final User user ) {
user . setKitTimestamp ( kitName , 0 ) ;
}
2015-04-15 06:06:16 +02:00
public void chargeUser ( final User user ) throws Exception {
charge . charge ( user ) ;
}
public long getNextUse ( final User user ) throws Exception {
if ( user . isAuthorized ( " essentials.kit.exemptdelay " ) ) {
return 0L ;
}
final Calendar time = new GregorianCalendar ( ) ;
double delay = 0 ;
try {
// Make sure delay is valid
delay = kit . containsKey ( " delay " ) ? ( ( Number ) kit . get ( " delay " ) ) . doubleValue ( ) : 0 . 0d ;
2020-10-03 19:46:05 +02:00
} catch ( final Exception e ) {
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( " kitError2 " ) ;
2015-04-15 06:06:16 +02:00
}
// When was the last kit used?
final long lastTime = user . getKitTimestamp ( kitName ) ;
// When can be use the kit again?
final Calendar delayTime = new GregorianCalendar ( ) ;
delayTime . setTimeInMillis ( lastTime ) ;
delayTime . add ( Calendar . SECOND , ( int ) delay ) ;
delayTime . add ( Calendar . MILLISECOND , ( int ) ( ( delay * 1000 . 0 ) % 1000 . 0 ) ) ;
if ( lastTime = = 0L | | lastTime > time . getTimeInMillis ( ) ) {
2015-04-17 21:48:23 +02:00
// If we have no record of kit use, or its corrupted, give them benefit of the doubt.
2015-04-15 06:06:16 +02:00
return 0L ;
} else if ( delay < 0d ) {
// If the kit has a negative kit time, it can only be used once.
return - 1 ;
} else if ( delayTime . before ( time ) ) {
// If the kit was used in the past, but outside the delay time, it can be used.
return 0L ;
} else {
// If the kit has been used recently, return the next time it can be used.
return delayTime . getTimeInMillis ( ) ;
}
}
2015-04-20 21:33:36 +02:00
@Deprecated
2015-04-15 06:06:16 +02:00
public List < String > getItems ( final User user ) throws Exception {
2015-04-20 21:33:36 +02:00
return getItems ( ) ;
}
public List < String > getItems ( ) throws Exception {
2015-04-15 06:06:16 +02:00
if ( kit = = null ) {
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( " kitNotFound " ) ;
2015-04-15 06:06:16 +02:00
}
try {
2020-04-25 14:08:57 +02:00
final List < String > itemList = new ArrayList < > ( ) ;
2015-04-15 06:06:16 +02:00
final Object kitItems = kit . get ( " items " ) ;
if ( kitItems instanceof List ) {
2020-10-03 19:46:05 +02:00
for ( final Object item : ( List ) kitItems ) {
2015-04-15 06:06:16 +02:00
if ( item instanceof String ) {
itemList . add ( item . toString ( ) ) ;
continue ;
}
throw new Exception ( " Invalid kit item: " + item . toString ( ) ) ;
}
return itemList ;
}
throw new Exception ( " Invalid item list " ) ;
2020-10-03 19:46:05 +02:00
} catch ( final Exception e ) {
2015-04-15 06:06:16 +02:00
ess . getLogger ( ) . log ( Level . WARNING , " Error parsing kit " + kitName + " : " + e . getMessage ( ) ) ;
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( e , " kitError2 " ) ;
2015-04-15 06:06:16 +02:00
}
}
2019-10-13 23:00:11 +02:00
public boolean expandItems ( final User user ) throws Exception {
return expandItems ( user , getItems ( user ) ) ;
2015-04-15 06:06:16 +02:00
}
2019-10-13 23:00:11 +02:00
public boolean expandItems ( final User user , final List < String > items ) throws Exception {
2015-04-15 06:06:16 +02:00
try {
2020-10-03 19:46:05 +02:00
final IText input = new SimpleTextInput ( items ) ;
final IText output = new KeywordReplacer ( input , user . getSource ( ) , ess , true , true ) ;
2015-04-15 06:06:16 +02:00
2020-10-03 19:46:05 +02:00
final KitClaimEvent event = new KitClaimEvent ( user , this ) ;
2020-05-09 22:19:51 +02:00
Bukkit . getPluginManager ( ) . callEvent ( event ) ;
if ( event . isCancelled ( ) ) {
return false ;
}
2015-04-15 06:06:16 +02:00
boolean spew = false ;
final boolean allowUnsafe = ess . getSettings ( ) . allowUnsafeEnchantments ( ) ;
2021-01-08 21:39:32 +01:00
final boolean autoEquip = ess . getSettings ( ) . isKitAutoEquip ( ) ;
2020-10-03 19:46:05 +02:00
final List < ItemStack > itemList = new ArrayList < > ( ) ;
final List < String > commandQueue = new ArrayList < > ( ) ;
final List < String > moneyQueue = new ArrayList < > ( ) ;
2020-12-30 21:37:30 +01:00
final String currencySymbol = ess . getSettings ( ) . getCurrencySymbol ( ) . isEmpty ( ) ? " $ " : ess . getSettings ( ) . getCurrencySymbol ( ) ;
2020-10-03 19:46:05 +02:00
for ( final String kitItem : output . getLines ( ) ) {
2020-12-30 21:37:30 +01:00
if ( kitItem . startsWith ( " $ " ) | | kitItem . startsWith ( currencySymbol ) ) {
2020-07-01 22:51:10 +02:00
moneyQueue . add ( NumberUtil . sanitizeCurrencyString ( kitItem , ess ) ) ;
2015-04-15 06:06:16 +02:00
continue ;
}
2015-04-20 17:56:45 +02:00
if ( kitItem . startsWith ( " / " ) ) {
2015-04-17 21:48:23 +02:00
String command = kitItem . substring ( 1 ) ;
2020-10-03 19:46:05 +02:00
final String name = user . getName ( ) ;
2015-04-17 21:48:23 +02:00
command = command . replace ( " {player} " , name ) ;
2020-07-01 22:51:10 +02:00
commandQueue . add ( command ) ;
2015-04-17 21:48:23 +02:00
continue ;
}
2021-08-28 17:46:38 +02:00
final ItemStack stack ;
2021-06-26 22:03:27 +02:00
if ( kitItem . startsWith ( " @ " ) ) {
if ( ess . getSerializationProvider ( ) = = null ) {
2024-02-04 03:13:18 +01:00
ess . getLogger ( ) . log ( Level . WARNING , AdventureUtil . miniToLegacy ( tlLiteral ( " kitError3 " , kitName , user . getName ( ) ) ) ) ;
2021-06-26 22:03:27 +02:00
continue ;
}
2021-08-28 17:46:38 +02:00
stack = ess . getSerializationProvider ( ) . deserializeItem ( Base64Coder . decodeLines ( kitItem . substring ( 1 ) ) ) ;
} else {
final String [ ] parts = kitItem . split ( " + " ) ;
final ItemStack parseStack = ess . getItemDb ( ) . get ( parts [ 0 ] , parts . length > 1 ? Integer . parseInt ( parts [ 1 ] ) : 1 ) ;
2021-06-26 22:03:27 +02:00
2021-08-28 17:46:38 +02:00
if ( parseStack . getType ( ) = = Material . AIR ) {
continue ;
}
2015-04-15 06:06:16 +02:00
2021-08-28 17:46:38 +02:00
final MetaItemStack metaStack = new MetaItemStack ( parseStack ) ;
2015-04-15 06:06:16 +02:00
2021-08-28 17:46:38 +02:00
if ( parts . length > 2 ) {
// We pass a null sender here because kits should not do perm checks
metaStack . parseStringMeta ( null , allowUnsafe , parts , 2 , ess ) ;
}
2015-04-15 06:06:16 +02:00
2021-08-28 17:46:38 +02:00
stack = metaStack . getItemStack ( ) ;
2015-04-15 06:06:16 +02:00
}
2020-10-03 19:46:05 +02:00
2021-08-28 17:46:38 +02:00
itemList . add ( stack ) ;
2019-10-13 23:00:11 +02:00
}
2020-10-03 19:46:05 +02:00
2022-12-24 18:58:51 +01:00
final int maxStackSize = user . isAuthorized ( " essentials.oversizedstacks " ) ? ess . getSettings ( ) . getOversizedStackSize ( ) : 0 ;
2019-10-13 23:00:11 +02:00
final boolean isDropItemsIfFull = ess . getSettings ( ) . isDropItemsIfFull ( ) ;
2022-12-24 18:58:51 +01:00
2023-07-01 23:51:58 +02:00
final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent ( user , kitName , itemList ) ;
Bukkit . getPluginManager ( ) . callEvent ( itemsEvent ) ;
2022-12-24 18:58:51 +01:00
final ItemStack [ ] itemArray = itemList . toArray ( new ItemStack [ 0 ] ) ;
2023-07-01 23:51:58 +02:00
2022-12-24 18:58:51 +01:00
if ( ! isDropItemsIfFull & & ! Inventories . hasSpace ( user . getBase ( ) , maxStackSize , autoEquip , itemArray ) ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " kitInvFullNoDrop " ) ;
2022-12-24 18:58:51 +01:00
return false ;
}
final Map < Integer , ItemStack > leftover = Inventories . addItem ( user . getBase ( ) , maxStackSize , autoEquip , itemArray ) ;
if ( ! isDropItemsIfFull & & ! leftover . isEmpty ( ) ) {
// Inventories#hasSpace should prevent this state from EVER being reached; If it does, something has gone terribly wrong, and we should just give up and hope people report it :(
throw new IllegalStateException ( " Something has gone terribly wrong while adding items to the user's inventory. Please report this to the EssentialsX developers. Items left over: " + leftover + " . Original items: " + Arrays . toString ( itemArray ) ) ;
}
for ( final ItemStack itemStack : leftover . values ( ) ) {
int spillAmount = itemStack . getAmount ( ) ;
if ( maxStackSize ! = 0 ) {
itemStack . setAmount ( Math . min ( spillAmount , itemStack . getMaxStackSize ( ) ) ) ;
2019-10-13 23:00:11 +02:00
}
2022-12-24 18:58:51 +01:00
while ( spillAmount > 0 ) {
user . getWorld ( ) . dropItemNaturally ( user . getLocation ( ) , itemStack ) ;
spillAmount - = itemStack . getAmount ( ) ;
2019-10-13 23:00:11 +02:00
}
2022-12-24 18:58:51 +01:00
spew = true ;
2015-04-15 06:06:16 +02:00
}
user . getBase ( ) . updateInventory ( ) ;
2020-07-01 22:51:10 +02:00
// Process money & command queues
// Done after all items have been processed so commands are not run and money is not given if
// an error occurs during the item giving process
2020-10-03 19:46:05 +02:00
for ( final String valueString : moneyQueue ) {
final BigDecimal value = new BigDecimal ( valueString . trim ( ) ) ;
final Trade t = new Trade ( value , ess ) ;
2020-07-01 22:51:10 +02:00
t . pay ( user , OverflowType . DROP ) ;
}
2020-10-03 19:46:05 +02:00
for ( final String cmd : commandQueue ) {
2020-07-01 22:51:10 +02:00
Bukkit . dispatchCommand ( Bukkit . getConsoleSender ( ) , cmd ) ;
}
2015-04-15 06:06:16 +02:00
if ( spew ) {
2024-02-03 21:38:14 +01:00
user . sendTl ( " kitInvFull " ) ;
2015-04-15 06:06:16 +02:00
}
2020-10-03 19:46:05 +02:00
} catch ( final Exception e ) {
2015-04-15 06:06:16 +02:00
user . getBase ( ) . updateInventory ( ) ;
ess . getLogger ( ) . log ( Level . WARNING , e . getMessage ( ) ) ;
2024-02-03 21:38:14 +01:00
throw new TranslatableException ( e , " kitError2 " ) ;
2015-04-15 06:06:16 +02:00
}
2019-10-13 23:00:11 +02:00
return true ;
2015-04-15 06:06:16 +02:00
}
2011-12-08 05:44:18 +01:00
}