2018-08-22 20:15:56 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Baritone.
|
|
|
|
*
|
|
|
|
* Baritone is free software: you can redistribute it and/or modify
|
2018-09-17 22:11:40 +00:00
|
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
2018-08-22 20:15:56 +00:00
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Baritone 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
|
2018-09-17 22:11:40 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2018-08-22 20:15:56 +00:00
|
|
|
*
|
2018-09-17 22:11:40 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
2018-08-22 20:15:56 +00:00
|
|
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package baritone;
|
2018-08-14 00:15:59 +00:00
|
|
|
|
2018-08-14 22:19:35 +00:00
|
|
|
import net.minecraft.init.Blocks;
|
|
|
|
import net.minecraft.item.Item;
|
|
|
|
|
2018-08-14 22:04:41 +00:00
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.util.*;
|
|
|
|
|
2018-08-14 00:15:59 +00:00
|
|
|
/**
|
|
|
|
* Baritone's settings
|
|
|
|
*
|
|
|
|
* @author leijurv
|
|
|
|
*/
|
|
|
|
public class Settings {
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Allow Baritone to break blocks
|
|
|
|
*/
|
2018-08-14 22:04:41 +00:00
|
|
|
public Setting<Boolean> allowBreak = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Allow Baritone to sprint
|
|
|
|
*/
|
2018-08-19 20:18:48 +00:00
|
|
|
public Setting<Boolean> allowSprint = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Allow Baritone to place blocks
|
|
|
|
*/
|
2018-08-19 20:18:48 +00:00
|
|
|
public Setting<Boolean> allowPlace = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
2018-08-17 20:17:16 +00:00
|
|
|
/**
|
|
|
|
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
|
|
|
* because we want to generally conserve blocks which might be limited
|
|
|
|
*/
|
|
|
|
public Setting<Double> blockPlacementPenalty = new Setting<>(20D);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
|
|
|
* Reliability: questionable.
|
|
|
|
*/
|
2018-08-14 22:04:41 +00:00
|
|
|
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
2018-08-28 19:30:08 +00:00
|
|
|
/**
|
|
|
|
* Allow Baritone to assume it can walk on still water just like any other block.
|
|
|
|
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
|
|
|
|
2018-09-12 03:24:27 +00:00
|
|
|
/**
|
|
|
|
* Assume step functionality; don't jump on an Ascend.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> assumeStep = new Setting<>(false);
|
|
|
|
|
2018-09-12 03:50:29 +00:00
|
|
|
/**
|
|
|
|
* Assume safe walk functionality; don't sneak on a backplace traverse.
|
|
|
|
* <p>
|
|
|
|
* Warning: if you do something janky like sneak-backplace from an ender chest, if this is true
|
|
|
|
* it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
|
|
|
|
* against it. That's why this defaults to off.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> assumeSafeWalk = new Setting<>(false);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
|
|
|
*/
|
2018-08-30 01:35:57 +00:00
|
|
|
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
2018-08-14 22:19:35 +00:00
|
|
|
Item.getItemFromBlock(Blocks.DIRT),
|
|
|
|
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
|
|
|
Item.getItemFromBlock(Blocks.NETHERRACK)
|
2018-08-30 01:35:57 +00:00
|
|
|
)));
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-21 03:41:45 +00:00
|
|
|
/**
|
|
|
|
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
|
|
|
* pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> allowVines = new Setting<>(false);
|
|
|
|
|
2018-09-03 16:18:30 +00:00
|
|
|
/**
|
|
|
|
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
|
|
|
|
* everywhere in your base.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
|
|
|
|
|
2018-09-06 14:48:27 +00:00
|
|
|
/**
|
|
|
|
* You know what it is
|
2018-09-09 14:18:03 +00:00
|
|
|
* <p>
|
|
|
|
* But it's very unreliable and falls off when cornering like all the time so.
|
2018-09-06 14:48:27 +00:00
|
|
|
*/
|
2018-09-09 14:18:03 +00:00
|
|
|
public Setting<Boolean> allowParkour = new Setting<>(false);
|
2018-09-06 14:48:27 +00:00
|
|
|
|
2018-09-14 15:40:34 +00:00
|
|
|
/**
|
|
|
|
* Like parkour, but even more unreliable!
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> allowParkourPlace = new Setting<>(false);
|
|
|
|
|
2018-09-05 00:13:42 +00:00
|
|
|
/**
|
|
|
|
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* This is the big A* setting.
|
|
|
|
* As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
|
|
|
|
* 3.5 is always an underestimate, even if you are sprinting.
|
|
|
|
* If you're walking only (with allowSprint off) 4.6 is safe.
|
|
|
|
* Any value below 3.5 is never worth it. It's just more computation to find the same path, guaranteed.
|
|
|
|
* (specifically, it needs to be strictly slightly less than ActionCosts.WALK_ONE_BLOCK_COST, which is about 3.56)
|
|
|
|
* <p>
|
|
|
|
* Setting it at 3.57 or above with sprinting, or to 4.64 or above without sprinting, will result in
|
|
|
|
* faster computation, at the cost of a suboptimal path. Any value above the walk / sprint cost will result
|
|
|
|
* in it going straight at its goal, and not investigating alternatives, because the combined cost / heuristic
|
|
|
|
* metric gets better and better with each block, instead of slightly worse.
|
|
|
|
* <p>
|
|
|
|
* Finding the optimal path is worth it, so it's the default.
|
|
|
|
*/
|
2018-09-16 20:05:05 +00:00
|
|
|
public Setting<Double> costHeuristic = new Setting<>(3.5D);
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
// a bunch of obscure internal A* settings that you probably don't want to change
|
|
|
|
/**
|
|
|
|
* The maximum number of times it will fetch outside loaded or cached chunks before assuming that
|
|
|
|
* pathing has reached the end of the known area, and should therefore stop.
|
|
|
|
*/
|
2018-08-16 22:10:15 +00:00
|
|
|
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set to 1.0 to effectively disable this feature
|
2018-09-16 20:28:23 +00:00
|
|
|
*
|
|
|
|
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
|
2018-08-20 02:12:37 +00:00
|
|
|
*/
|
|
|
|
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.9);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
|
|
|
|
* and there's no point.
|
|
|
|
*/
|
2018-08-18 02:19:25 +00:00
|
|
|
public Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
|
|
|
|
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
|
2018-09-16 20:28:23 +00:00
|
|
|
*
|
|
|
|
* @see <a href="https://github.com/cabaletta/baritone/issues/144">Issue #144</a>
|
2018-08-20 02:12:37 +00:00
|
|
|
*/
|
2018-09-02 17:46:54 +00:00
|
|
|
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
2018-09-11 22:50:46 +00:00
|
|
|
/**
|
|
|
|
* If a movement's cost increases by more than this amount between calculation and execution (due to changes
|
|
|
|
* in the environment / world), cancel and recalculate
|
|
|
|
*/
|
|
|
|
public Setting<Double> maxCostIncrease = new Setting<>(10D);
|
|
|
|
|
2018-08-26 15:19:14 +00:00
|
|
|
/**
|
|
|
|
* Stop 5 movements before anything that made the path COST_INF.
|
|
|
|
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
|
|
|
|
* still be spreading lol
|
|
|
|
*/
|
|
|
|
public Setting<Integer> costVerificationLookahead = new Setting<>(5);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
|
|
|
|
*/
|
2018-08-20 00:27:33 +00:00
|
|
|
public Setting<Double> pathCutoffFactor = new Setting<>(0.9);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Only apply static cutoff for paths of at least this length (in terms of number of movements)
|
|
|
|
*/
|
2018-08-20 00:27:33 +00:00
|
|
|
public Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Start planning the next path once the remaining movements tick estimates sum up to less than this value
|
|
|
|
*/
|
|
|
|
public Setting<Integer> planningTickLookAhead = new Setting<>(100);
|
|
|
|
|
2018-08-20 14:11:15 +00:00
|
|
|
/**
|
|
|
|
* How far are you allowed to fall onto solid ground (without a water bucket)?
|
|
|
|
* 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
|
|
|
|
* Feather Falling IV, you might set it a bit higher, like 4 or 5.
|
|
|
|
*/
|
2018-08-22 00:16:00 +00:00
|
|
|
public Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* How far are you allowed to fall onto solid ground (with a water bucket)?
|
|
|
|
* It's not that reliable, so I've set it below what would kill an unarmored player (23)
|
|
|
|
*/
|
|
|
|
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
|
2018-08-20 14:11:15 +00:00
|
|
|
|
2018-08-26 15:12:57 +00:00
|
|
|
/**
|
|
|
|
* Is it okay to sprint through a descend followed by a diagonal?
|
|
|
|
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
|
|
|
|
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
|
|
|
|
|
2018-08-21 23:20:08 +00:00
|
|
|
/**
|
|
|
|
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
|
|
|
|
* doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path.
|
|
|
|
* Once a segment ends within chunk load range of the GoalBlock, it will go back to normal behavior
|
|
|
|
* of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
|
|
|
|
* your Y coordinate's accuracy doesn't matter at all until you get much much closer.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
|
|
|
|
|
2018-08-20 23:23:32 +00:00
|
|
|
/**
|
|
|
|
* If a movement takes this many ticks more than its initial cost estimate, cancel it
|
|
|
|
*/
|
|
|
|
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Pathing can never take longer than this
|
|
|
|
*/
|
2018-09-16 20:05:05 +00:00
|
|
|
public Setting<Long> pathTimeoutMS = new Setting<>(2000L);
|
2018-09-02 20:51:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Planning ahead while executing a segment can never take longer than this
|
|
|
|
*/
|
2018-09-16 20:05:05 +00:00
|
|
|
public Setting<Long> planAheadTimeoutMS = new Setting<>(4000L);
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* For debugging, consider nodes much much slower
|
|
|
|
*/
|
2018-08-18 02:19:25 +00:00
|
|
|
public Setting<Boolean> slowPath = new Setting<>(false);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Milliseconds between each node
|
|
|
|
*/
|
2018-09-16 20:05:05 +00:00
|
|
|
public Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The alternative timeout number when slowPath is on
|
|
|
|
*/
|
2018-09-16 20:05:05 +00:00
|
|
|
public Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
|
|
|
|
*/
|
2018-08-21 20:39:28 +00:00
|
|
|
public Setting<Boolean> chunkCaching = new Setting<>(true);
|
2018-08-18 02:19:25 +00:00
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Print all the debug messages to chat
|
|
|
|
*/
|
2018-08-18 02:19:25 +00:00
|
|
|
public Setting<Boolean> chatDebug = new Setting<>(true);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
|
|
|
|
* something else
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> chatControl = new Setting<>(true);
|
|
|
|
|
2018-09-02 19:06:00 +00:00
|
|
|
/**
|
|
|
|
* A second override over chatControl to force it on
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> removePrefix = new Setting<>(false);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Render the path
|
|
|
|
*/
|
2018-08-18 02:19:25 +00:00
|
|
|
public Setting<Boolean> renderPath = new Setting<>(true);
|
2018-08-20 02:12:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Render the goal
|
|
|
|
*/
|
2018-08-18 02:19:25 +00:00
|
|
|
public Setting<Boolean> renderGoal = new Setting<>(true);
|
|
|
|
|
2018-08-20 02:12:37 +00:00
|
|
|
/**
|
|
|
|
* Line width of the path when rendered, in pixels
|
|
|
|
*/
|
|
|
|
public Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Line width of the goal when rendered, in pixels
|
|
|
|
*/
|
|
|
|
public Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
|
|
|
|
* Improves FPS.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> fadePath = new Setting<>(false);
|
2018-08-14 22:04:41 +00:00
|
|
|
|
2018-08-21 23:19:20 +00:00
|
|
|
/**
|
|
|
|
* Move without having to force the client-sided rotations
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> freeLook = new Setting<>(true);
|
|
|
|
|
2018-08-23 03:07:27 +00:00
|
|
|
/**
|
|
|
|
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
|
|
|
|
* <p>
|
|
|
|
* At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
|
|
|
|
* directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
|
|
|
|
|
2018-08-22 19:04:44 +00:00
|
|
|
/**
|
|
|
|
* Exclusively use cached chunks for pathing
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
|
|
|
|
|
2018-08-24 02:01:35 +00:00
|
|
|
/**
|
|
|
|
* Whether or not to use the "#" command prefix
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> prefix = new Setting<>(false);
|
|
|
|
|
2018-09-14 16:05:29 +00:00
|
|
|
/**
|
|
|
|
* true: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
|
|
|
* false: works on cosmic prisons
|
|
|
|
* <p>
|
|
|
|
* LOL
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
|
|
|
|
|
2018-09-14 23:45:51 +00:00
|
|
|
/**
|
|
|
|
* Don't stop walking forward when you need to break blocks in your way
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
|
|
|
|
2018-09-15 17:34:02 +00:00
|
|
|
/**
|
|
|
|
* Rescan for the goal once every 5 ticks.
|
|
|
|
* Set to 0 to disable.
|
|
|
|
*/
|
|
|
|
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
|
|
|
|
2018-09-15 19:51:37 +00:00
|
|
|
/**
|
|
|
|
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
|
|
|
*/
|
|
|
|
public Setting<Integer> axisHeight = new Setting<>(120);
|
|
|
|
|
2018-09-16 20:00:44 +00:00
|
|
|
/**
|
|
|
|
* When mining block of a certain type, try to mine two at once instead of one.
|
|
|
|
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
|
|
|
|
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> forceInternalMining = new Setting<>(true);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Modification to the previous setting, only has effect if forceInternalMining is true
|
|
|
|
* If true, only apply the previous setting if the block adjacent to the goal isn't air.
|
|
|
|
*/
|
|
|
|
public Setting<Boolean> internalMiningAirException = new Setting<>(true);
|
|
|
|
|
2018-09-17 17:36:39 +00:00
|
|
|
/**
|
|
|
|
* The actual GoalNear is set this distance away from the entity you're following
|
|
|
|
* <p>
|
|
|
|
* For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
|
|
|
|
*/
|
|
|
|
public Setting<Double> followOffsetDistance = new Setting<>(0D);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The actual GoalNear is set in this direction from the entity you're following
|
|
|
|
*/
|
|
|
|
public Setting<Float> followOffsetDirection = new Setting<>(0F);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The radius (for the GoalNear) of how close to your target position you actually have to be
|
|
|
|
*/
|
|
|
|
public Setting<Integer> followRadius = new Setting<>(3);
|
|
|
|
|
2018-08-19 20:18:48 +00:00
|
|
|
public final Map<String, Setting<?>> byLowerName;
|
2018-08-14 22:04:41 +00:00
|
|
|
public final List<Setting<?>> allSettings;
|
|
|
|
|
|
|
|
public class Setting<T> {
|
|
|
|
public T value;
|
|
|
|
private String name;
|
2018-08-14 22:16:38 +00:00
|
|
|
private final Class<T> klass;
|
2018-08-14 22:04:41 +00:00
|
|
|
|
2018-08-21 23:19:20 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2018-08-14 22:16:38 +00:00
|
|
|
private Setting(T value) {
|
2018-08-14 22:24:23 +00:00
|
|
|
if (value == null) {
|
|
|
|
throw new IllegalArgumentException("Cannot determine value type class from null");
|
|
|
|
}
|
2018-08-14 22:04:41 +00:00
|
|
|
this.value = value;
|
2018-08-14 22:16:38 +00:00
|
|
|
this.klass = (Class<T>) value.getClass();
|
2018-08-14 22:04:41 +00:00
|
|
|
}
|
2018-08-14 00:15:59 +00:00
|
|
|
|
2018-08-21 23:19:20 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2018-08-16 22:10:15 +00:00
|
|
|
public final <K extends T> K get() {
|
|
|
|
return (K) value;
|
2018-08-14 22:04:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public final String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2018-08-14 22:22:52 +00:00
|
|
|
public Class<T> getValueClass() {
|
|
|
|
return klass;
|
|
|
|
}
|
|
|
|
|
2018-08-14 22:04:41 +00:00
|
|
|
public String toString() {
|
|
|
|
return name + ": " + value;
|
|
|
|
}
|
2018-08-14 00:15:59 +00:00
|
|
|
}
|
2018-08-14 22:04:41 +00:00
|
|
|
|
|
|
|
// here be dragons
|
|
|
|
|
|
|
|
{
|
|
|
|
Field[] temp = getClass().getFields();
|
|
|
|
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
|
|
|
|
List<Setting<?>> tmpAll = new ArrayList<>();
|
2018-08-14 22:16:38 +00:00
|
|
|
try {
|
|
|
|
for (Field field : temp) {
|
|
|
|
if (field.getType().equals(Setting.class)) {
|
2018-08-21 23:19:20 +00:00
|
|
|
Setting<?> setting = (Setting<?>) field.get(this);
|
2018-08-14 22:04:41 +00:00
|
|
|
String name = field.getName();
|
|
|
|
setting.name = name;
|
2018-08-19 20:18:48 +00:00
|
|
|
name = name.toLowerCase();
|
2018-08-14 22:04:41 +00:00
|
|
|
if (tmpByName.containsKey(name)) {
|
|
|
|
throw new IllegalStateException("Duplicate setting name");
|
|
|
|
}
|
|
|
|
tmpByName.put(name, setting);
|
|
|
|
tmpAll.add(setting);
|
|
|
|
}
|
|
|
|
}
|
2018-08-14 22:16:38 +00:00
|
|
|
} catch (IllegalAccessException e) {
|
2018-09-17 00:58:35 +00:00
|
|
|
throw new IllegalStateException(e);
|
2018-08-14 22:04:41 +00:00
|
|
|
}
|
2018-08-19 20:18:48 +00:00
|
|
|
byLowerName = Collections.unmodifiableMap(tmpByName);
|
2018-08-14 22:04:41 +00:00
|
|
|
allSettings = Collections.unmodifiableList(tmpAll);
|
|
|
|
}
|
|
|
|
|
2018-08-21 23:19:20 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2018-08-27 18:39:36 +00:00
|
|
|
public <T> List<Setting<T>> getAllValuesByType(Class<T> klass) {
|
2018-08-25 23:35:41 +00:00
|
|
|
List<Setting<T>> result = new ArrayList<>();
|
2018-08-14 22:04:41 +00:00
|
|
|
for (Setting<?> setting : allSettings) {
|
2018-08-27 19:35:30 +00:00
|
|
|
if (setting.getValueClass().equals(klass)) {
|
2018-08-14 22:16:38 +00:00
|
|
|
result.add((Setting<T>) setting);
|
2018-08-14 22:04:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
Settings() { }
|
2018-08-14 00:15:59 +00:00
|
|
|
}
|