From 5d15dce9293f7c37089be3adfe0768de425838e2 Mon Sep 17 00:00:00 2001 From: Jordan Byrne Date: Wed, 21 Feb 2018 14:38:10 +1000 Subject: $ Tree Farmer Work. % Package cleanup. - Removed /Bed command. --- .../api/analytics/AnalyticsLoggingPlugin.java | 39 --- .../gtPlusPlus/api/analytics/BlockingFlush.java | 67 ----- .../gtPlusPlus/api/analytics/SegmentAnalytics.java | 271 ------------------ .../gtPlusPlus/api/analytics/SegmentHelper.java | 81 ------ .../api/damage/BaseCustomDamageSource.java | 22 -- .../gtPlusPlus/api/damage/DamageTeslaTower.java | 1 + .../gtPlusPlus/api/helpers/MaterialHelper.java | 18 ++ .../gtPlusPlus/api/interfaces/IEntityCatcher.java | 2 +- .../gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java | 271 ------------------ src/Java/gtPlusPlus/api/objects/ChunkManager.java | 309 --------------------- src/Java/gtPlusPlus/api/objects/DimChunkPos.java | 53 ---- src/Java/gtPlusPlus/api/objects/GenericStack.java | 41 --- .../gtPlusPlus/api/objects/MaterialHelper.java | 18 -- src/Java/gtPlusPlus/api/objects/XSTR.java | 266 ------------------ src/Java/gtPlusPlus/api/objects/data/AutoMap.java | 77 +++++ src/Java/gtPlusPlus/api/objects/data/Pair.java | 27 ++ src/Java/gtPlusPlus/api/objects/data/Quad.java | 33 +++ src/Java/gtPlusPlus/api/objects/data/Triplet.java | 27 ++ .../gtPlusPlus/api/objects/minecraft/BlockPos.java | 85 ++++++ .../api/objects/minecraft/ChunkManager.java | 309 +++++++++++++++++++++ .../api/objects/minecraft/DimChunkPos.java | 52 ++++ .../api/objects/minecraft/GenericStack.java | 41 +++ .../api/objects/random/CSPRNG_DO_NOT_USE.java | 271 ++++++++++++++++++ src/Java/gtPlusPlus/api/objects/random/XSTR.java | 266 ++++++++++++++++++ 24 files changed, 1208 insertions(+), 1439 deletions(-) delete mode 100644 src/Java/gtPlusPlus/api/analytics/AnalyticsLoggingPlugin.java delete mode 100644 src/Java/gtPlusPlus/api/analytics/BlockingFlush.java delete mode 100644 src/Java/gtPlusPlus/api/analytics/SegmentAnalytics.java delete mode 100644 src/Java/gtPlusPlus/api/analytics/SegmentHelper.java delete mode 100644 src/Java/gtPlusPlus/api/damage/BaseCustomDamageSource.java create mode 100644 src/Java/gtPlusPlus/api/helpers/MaterialHelper.java delete mode 100644 src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java delete mode 100644 src/Java/gtPlusPlus/api/objects/ChunkManager.java delete mode 100644 src/Java/gtPlusPlus/api/objects/DimChunkPos.java delete mode 100644 src/Java/gtPlusPlus/api/objects/GenericStack.java delete mode 100644 src/Java/gtPlusPlus/api/objects/MaterialHelper.java delete mode 100644 src/Java/gtPlusPlus/api/objects/XSTR.java create mode 100644 src/Java/gtPlusPlus/api/objects/data/AutoMap.java create mode 100644 src/Java/gtPlusPlus/api/objects/data/Pair.java create mode 100644 src/Java/gtPlusPlus/api/objects/data/Quad.java create mode 100644 src/Java/gtPlusPlus/api/objects/data/Triplet.java create mode 100644 src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java create mode 100644 src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java create mode 100644 src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java create mode 100644 src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java create mode 100644 src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java create mode 100644 src/Java/gtPlusPlus/api/objects/random/XSTR.java (limited to 'src/Java/gtPlusPlus/api') diff --git a/src/Java/gtPlusPlus/api/analytics/AnalyticsLoggingPlugin.java b/src/Java/gtPlusPlus/api/analytics/AnalyticsLoggingPlugin.java deleted file mode 100644 index 2423eaa65c..0000000000 --- a/src/Java/gtPlusPlus/api/analytics/AnalyticsLoggingPlugin.java +++ /dev/null @@ -1,39 +0,0 @@ -package gtPlusPlus.api.analytics; - -import com.segment.analytics.Analytics; -import com.segment.analytics.Callback; -import com.segment.analytics.Log; -import com.segment.analytics.Plugin; -import com.segment.analytics.messages.Message; - -import gtPlusPlus.api.objects.Logger; - -/** - * A {@link Plugin} implementation that redirects client logs to standard output and logs callback - * events. - */ -public class AnalyticsLoggingPlugin implements Plugin { - @Override public void configure(Analytics.Builder builder) { - builder.log(new Log() { - @Override public void print(Level level, String format, Object... args) { - Logger.WARNING(level + ":\t" + String.format(format, args)); - } - - @Override public void print(Level level, Throwable error, String format, Object... args) { - Logger.WARNING(level + ":\t" + String.format(format, args)); - //Utils.LOG_WARNING(error); - } - }); - - builder.callback(new Callback() { - @Override public void success(Message message) { - Logger.WARNING("Uploaded " + message); - } - - @Override public void failure(Message message, Throwable throwable) { - Logger.WARNING("Could not upload " + message); - //Utils.LOG_WARNING(throwable); - } - }); - } -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/analytics/BlockingFlush.java b/src/Java/gtPlusPlus/api/analytics/BlockingFlush.java deleted file mode 100644 index dddb37fefb..0000000000 --- a/src/Java/gtPlusPlus/api/analytics/BlockingFlush.java +++ /dev/null @@ -1,67 +0,0 @@ -package gtPlusPlus.api.analytics; - -import com.segment.analytics.Analytics; -import com.segment.analytics.Callback; -import com.segment.analytics.MessageTransformer; -import com.segment.analytics.Plugin; -import com.segment.analytics.messages.Message; -import com.segment.analytics.messages.MessageBuilder; -import java.util.concurrent.Phaser; - -/** - * The {@link Analytics} class doesn't come with a blocking {@link Analytics#flush()} implementation - * out of the box. It's trivial to build one using a {@link Phaser} that monitors requests and is - * able to block until they're uploaded. - * - *

- * BlockingFlush mBlockingFlush = BlockingFlush.create();
- * Analytics mHelper = Analytics.builder(writeKey)
- *      .plugin(mBlockingFlush)
- *      .build();
- *
- * // Do some work.
- *
- * mHelper.flush(); // Trigger a flush.
- * mBlockingFlush.block(); // Block until the flush completes.
- * mHelper.shutdown(); // Shut down after the flush is complete.
- * 
- */ -public class BlockingFlush { - - public static BlockingFlush create() { - return new BlockingFlush(); - } - - BlockingFlush() { - this.phaser = new Phaser(1); - } - - final Phaser phaser; - - public Plugin plugin() { - return new Plugin() { - @Override public void configure(Analytics.Builder builder) { - builder.messageTransformer(new MessageTransformer() { - @Override public boolean transform(MessageBuilder builder) { - phaser.register(); - return true; - } - }); - - builder.callback(new Callback() { - @Override public void success(Message message) { - phaser.arrive(); - } - - @Override public void failure(Message message, Throwable throwable) { - phaser.arrive(); - } - }); - } - }; - } - - public void block() { - phaser.arriveAndAwaitAdvance(); - } -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/analytics/SegmentAnalytics.java b/src/Java/gtPlusPlus/api/analytics/SegmentAnalytics.java deleted file mode 100644 index c4ef82b9ef..0000000000 --- a/src/Java/gtPlusPlus/api/analytics/SegmentAnalytics.java +++ /dev/null @@ -1,271 +0,0 @@ -package gtPlusPlus.api.analytics; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Phaser; - -import com.mojang.authlib.GameProfile; -import com.segment.analytics.Analytics; - -import gtPlusPlus.api.objects.Logger; -import gtPlusPlus.core.lib.CORE; -import gtPlusPlus.core.lib.LoadedMods; -import gtPlusPlus.core.util.Utils; -import gtPlusPlus.core.util.player.PlayerUtils; -import gtPlusPlus.core.util.uuid.UUIDGenerator; -import gtPlusPlus.core.util.uuid.UUIDUtils; -import ic2.core.IC2; -import net.minecraft.entity.player.EntityPlayer; - -public class SegmentAnalytics { - - //Globally Enabled - public static boolean isEnabled = true; - - //Analytics Map with IDs - public static final Map sAnalyticsMasterList = new ConcurrentHashMap(); - //ID count - private static int sAnalyticsMapID = 0; - - //Analytics Player Mapping - public static final Map sAnalyticsToPlayermap = new ConcurrentHashMap(); - - //Set some Vars - final BlockingFlush mBlockingFlush; - final SegmentHelper mHelper; - final UUIDGenerator mUuidGenerator; - - public final GameProfile mLocalProfile; - public final String mLocalName; - public final UUID mUUID; - public final String mUserName; - public final String mAnonymousId; - protected Map mProperties = new LinkedHashMap<>(); - final protected Phaser mPhaser; - - //Build a new instance of this class - public SegmentAnalytics(EntityPlayer mPlayer){ - LOG("Initializing Segment for "+mPlayer.getDisplayName()); - - //Give this Object an ID - int currentID = sAnalyticsMapID; - sAnalyticsMapID++; - - //Map this Object to it's ID and a Player UUID. - sAnalyticsMasterList.put(currentID, this); - sAnalyticsToPlayermap.put(mPlayer.getUniqueID(), currentID); - - //Create a Phaser - this.mPhaser = new Phaser(1); - - //Set vars for player - this.mLocalProfile = mPlayer.getGameProfile(); - this.mLocalName = mLocalProfile.getName(); - this.mUUID = PlayerUtils.getPlayersUUIDByName(mLocalName); - this.mUserName = mUUID.toString(); - this.mAnonymousId = getStringForm(generateIdForSession()); - - //Create a new UUID generator. - this.mUuidGenerator = new UUIDGenerator(); - - //Use Segment Analytics instead of plain Google Analytics. - this.mBlockingFlush = BlockingFlush.create(); - this.mHelper = SegmentHelper.getInstance(); - initTimer(mPlayer); - } - - //Sets vars and stops Analytics running if the player profile is invalid. - private boolean canProcess(){ - //Invalid Player Profile - if (mLocalProfile == null || !isEnabled){ - return false; - } - if (mLocalName == null || mUUID == null || mUserName == null || mAnonymousId == null){ - //LOG("One player var remained null, returning false."); - return false; - } - if (mLocalName != null && mUUID != null && mUserName != null && mAnonymousId != null){ - //LOG("All player vars are ok, returning true."); - return true; - } - LOG("Something went wrong, returning false."); - return false; - } - - - public void submitInitData(EntityPlayer mPlayer){ - if (!canProcess()){ - return; - } - mProperties = new LinkedHashMap<>(); - mProperties.put("username", mLocalName); - mProperties.put("gt_version", Utils.getGregtechVersionAsString()); - if (LoadedMods.IndustrialCraft2){ - mProperties.put("ic2_version", IC2.VERSION); - } - mProperties.put("country_code", CORE.USER_COUNTRY); - mProperties.put("gtnh", CORE.GTNH); - - LOG("Created new Data packet, queued for submission."); - - //Old Code, now passed to Helper Class - /*mHelper.enqueue(IdentifyMessage.builder() - .userId(mUserName) //Save Username as UUID, for future sessions to attach to. - .traits(mProperties) - //.anonymousId(mAnonymousId) //Save Random Session UUID - );*/ - - mHelper.addUser(this.mUserName, mProperties); - - if (CORE.GTNH){ - mHelper.groupUser("GT:NewHorizons", this.mUserName); - } - else { - mHelper.groupUser("GT:Vanilla", this.mUserName); - } - - } - - public void submitTrackingData(String aActionPerformed){ - submitTrackingData(aActionPerformed, null); - } - - public void submitTrackingData(String aActionPerformed, Object aObject){ - if (!canProcess()){ - return; - } - - Map properties = new LinkedHashMap<>(); - properties.put("blockType", aObject); - String mObjectAsString = "Unknown"; - - if (aObject != null){ - mObjectAsString = aObject.toString(); - } - - LOG("Queued submission of data for event "+aActionPerformed+". This was performed on "+mObjectAsString+"."); - - mHelper.trackUser(this.mUserName, aActionPerformed, properties); - - //Old Code, now passed to Helper Class - /*mHelper.enqueue(TrackMessage.builder(aActionPerformed) // - .userId(mUserName) // Save Username as UUID, for future sessions to attach to. - .properties(mProperties) //Save Stats - //.anonymousId(mAnonymousId) //Save Random Session UUID - ); - flushData(); - */ - } - - public void flushData(){ - getAnalyticObject().flush(); - } - - public void flushDataFinal(){ - LOG("Flushing all data from Queue to Segment Analytics database."); - getAnalyticObject().flush(); - mBlockingFlush.block(); - mPhaser.arriveAndAwaitAdvance(); - getAnalyticObject().shutdown(); - /*try { - this.finalize(); - } - catch (Throwable e) { - Utils.LOG_INFO("Could not finalize Analytics Object."); - }*/ - } - - public UUID generateIdForSession(){ - return UUIDUtils.getUUIDFromBytes(generateUUID()); - } - - private final byte[] generateUUID(){ - byte[] mUUID; - - if (this.mUuidGenerator != null){ - try { - if ((mUUID = mUuidGenerator.next(4)) != null){ - LOG("Generated Type 4 UUID for Session ID."); - return mUUID; - } - else if ((mUUID = mUuidGenerator.next(1)) != null){ - LOG("Generated Type 1 UUID for Session ID."); - return mUUID; - } - } - catch (Throwable t){ - t.printStackTrace(); - } - } - - LOG("Generated Type 3 UUID for Session ID."); - return UUIDUtils.getBytesFromUUID(UUID.randomUUID()); - - } - - public final String getStringForm(UUID mID){ - return mID.toString(); - } - - // Non-Dev Comments - public static void LOG(final String s) { - if (CORE.DEBUG){ - Logger.getLogger().info("[Analytics] "+s); - } - } - - public static SegmentAnalytics getAnalyticsForPlayer(EntityPlayer mPlayer){ - try { - if (mPlayer != null){ - if (SegmentAnalytics.sAnalyticsToPlayermap.containsKey(mPlayer.getUniqueID())){ - int ID = sAnalyticsToPlayermap.get(mPlayer.getUniqueID()); - return SegmentAnalytics.sAnalyticsMasterList.get(ID); - } - else { - LOG("Map does not contain Player."); - } - } - else { - LOG("Invalid Player."); - } - } - catch (Throwable t){ - t.printStackTrace(); - } - return null; - } - - public final Analytics getAnalyticObject() { - return mHelper.getAnalyticsClient(); - } - - public final Map getPlayerProperties(){ - return this.mProperties; - } - - - public Timer initTimer(EntityPlayer mPlayer) { - Timer timer; - timer = new Timer(); - timer.schedule(new initPlayer(mPlayer), 2 * 1000); - return timer; - } - - //Timer Task for notifying the player. - class initPlayer extends TimerTask { - final EntityPlayer aPlayer; - public initPlayer(EntityPlayer mPlayer) { - this.aPlayer = mPlayer; - } - @Override - public void run() { - //Let us submit a doorknock to Segment to let them know who this is. - submitInitData(aPlayer); - } - } - -} diff --git a/src/Java/gtPlusPlus/api/analytics/SegmentHelper.java b/src/Java/gtPlusPlus/api/analytics/SegmentHelper.java deleted file mode 100644 index 6e264fe1d2..0000000000 --- a/src/Java/gtPlusPlus/api/analytics/SegmentHelper.java +++ /dev/null @@ -1,81 +0,0 @@ -package gtPlusPlus.api.analytics; - -import com.segment.analytics.Analytics; -import com.segment.analytics.Callback; -import com.segment.analytics.messages.Message; -import com.segment.analytics.messages.TrackMessage; -import com.segment.analytics.messages.*; -import java.util.Map; - -public class SegmentHelper implements Callback { - - /** - * Credits to Author: FLAMINSAGANAKI/Theodore Mavrakis - * http://domisydev.com/2015/11/05/using-segment-analytics-in-your-java-servlet/ - */ - - private static final String writeKey = "EDOWl9peleGlUqe1ZwTqKDyuTMFhyT4k"; - private static volatile SegmentHelper segment = new SegmentHelper(); - private Analytics analytics; - - public SegmentHelper(){ - try{ - this.analytics = Analytics.builder(writeKey).callback(this).build(); - }catch(Exception e){ - SegmentAnalytics.LOG("exception while creating Analytics : " + e); - } - } - - public static SegmentHelper getInstance(){ - return segment; - } - - public Analytics getAnalyticsClient(){ - return segment.analytics; - } - - public void success(Message message) { - SegmentAnalytics.LOG("Successfully uploaded " + message); - } - - public void failure(Message message, Throwable throwable) { - SegmentAnalytics.LOG("Could not upload " + message); - } - - public void addUser(String user_id, Map properties) { - try { - this.analytics.enqueue(IdentifyMessage.builder().userId(user_id).traits(properties)); - //trackUser(user_id, "Logged In", properties); - } catch (Exception e) { - SegmentAnalytics.LOG("Exception in addUser() - " + e); - } - } - - public void trackUser(String user_id, String description, Map properties) { - try { - this.analytics.enqueue(TrackMessage.builder(description).userId(user_id).properties(properties)); - } catch (Exception e) { - SegmentAnalytics.LOG("Exception in trackUser() - " + e); - } - } - - public void trackUser(String user_id, String description) { - try { - this.analytics.enqueue(TrackMessage.builder(description).userId(user_id)); - } catch (Exception e) { - SegmentAnalytics.LOG("Exception in trackUser() - " + e); - } - } - - public void groupUser(String group_id, String user_id) { - try { - this.analytics.enqueue(GroupMessage.builder(group_id).userId(user_id)); - } catch (Exception e) { - SegmentAnalytics.LOG("Exception in groupUser() - " + e); - } - } - - public static void main(String[] args){ - - } -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/damage/BaseCustomDamageSource.java b/src/Java/gtPlusPlus/api/damage/BaseCustomDamageSource.java deleted file mode 100644 index 24348988d6..0000000000 --- a/src/Java/gtPlusPlus/api/damage/BaseCustomDamageSource.java +++ /dev/null @@ -1,22 +0,0 @@ -package gtPlusPlus.api.damage; - -import net.minecraft.entity.Entity; -import net.minecraft.util.EntityDamageSourceIndirect; - -public class BaseCustomDamageSource extends EntityDamageSourceIndirect { - - public BaseCustomDamageSource(String name, Entity transmitter, Entity indirectSource) { - super(name, transmitter, indirectSource); - this.setDifficultyScaled(); - } - - /** - * Return whether this damage source will have its damage amount scaled based on the current difficulty. - */ - public boolean isDifficultyScaled() - { - return true; - } - - -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/damage/DamageTeslaTower.java b/src/Java/gtPlusPlus/api/damage/DamageTeslaTower.java index ada2ba5c3d..ecde9fe930 100644 --- a/src/Java/gtPlusPlus/api/damage/DamageTeslaTower.java +++ b/src/Java/gtPlusPlus/api/damage/DamageTeslaTower.java @@ -1,5 +1,6 @@ package gtPlusPlus.api.damage; +import gtPlusPlus.core.world.damage.BaseCustomDamageSource; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ChatComponentTranslation; diff --git a/src/Java/gtPlusPlus/api/helpers/MaterialHelper.java b/src/Java/gtPlusPlus/api/helpers/MaterialHelper.java new file mode 100644 index 0000000000..bb30727992 --- /dev/null +++ b/src/Java/gtPlusPlus/api/helpers/MaterialHelper.java @@ -0,0 +1,18 @@ +package gtPlusPlus.api.helpers; + +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gtPlusPlus.core.material.Material; +import gtPlusPlus.core.util.item.ItemUtils; +import net.minecraft.item.ItemStack; + +public class MaterialHelper { + + public static ItemStack getComponentFromMaterial(OrePrefixes oreprefix, Material material, int amount){ + return ItemUtils.getOrePrefixStack(oreprefix, material, amount); + } + public static ItemStack getComponentFromGtMaterial(OrePrefixes oreprefix, Materials material, int amount){ + return ItemUtils.getGregtechOreStack(oreprefix, material, amount); + } + +} diff --git a/src/Java/gtPlusPlus/api/interfaces/IEntityCatcher.java b/src/Java/gtPlusPlus/api/interfaces/IEntityCatcher.java index ca2d80de53..12813e1dd0 100644 --- a/src/Java/gtPlusPlus/api/interfaces/IEntityCatcher.java +++ b/src/Java/gtPlusPlus/api/interfaces/IEntityCatcher.java @@ -1,6 +1,6 @@ package gtPlusPlus.api.interfaces; -import gtPlusPlus.core.util.array.BlockPos; +import gtPlusPlus.api.objects.minecraft.BlockPos; import net.minecraft.entity.Entity; import net.minecraft.item.ItemStack; import net.minecraft.world.World; diff --git a/src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java b/src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java deleted file mode 100644 index 19200846ca..0000000000 --- a/src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2005, Nick Galbreath -- nickg [at] modp [dot] com - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of the modp.com nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This is the standard "new" BSD license: - * http://www.opensource.org/licenses/bsd-license.php - */ - -package gtPlusPlus.api.objects; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Random; - -import gtPlusPlus.api.interfaces.IRandomGenerator; -import gtPlusPlus.core.util.Utils; - -/** - * The Blum-Blum-Shub random number generator. - * - *

- * The Blum-Blum-Shub is a "cryptographically secure" random number - * generator. It has been proven that predicting the ouput - * is equivalent to factoring n, a large integer generated - * from two prime numbers. - *

- * - *

- * The Algorithm: - *

- *
    - *
  1. - * (setup) generate two secret prime numbers p, q such that - * pq, p ≡ 3 mod 4, q ≡ 3 mod 4. - *
  2. - *
  3. (setup) compute n = pq. n can be re-used, but - * p, and q are secret and should be disposed of.
  4. - *
  5. Generate a (secure) random seed s in the range [1, n -1] - * such that gcd(s, n) = 1. - *
  6. Compute x = s2 mod n
  7. - *
  8. Compute a single random bit with: - *
      - *
    1. x = x2 mod n
    2. - *
    3. return Least-Significant-Bit(x) (i.e. x & 1)
    4. - *
    - * Repeat as necessary. - *
  9. - *
- * - *

- * The code originally appeared in Cryptography for - * Internet and Database Applications , Chapter 4, pages 174-177 - *

- *

- * More details are in the Handbook of Applied Cryptography, - * Section 5.5.2 - *

- * - * @author Nick Galbreath -- nickg [at] modp [dot] com - * @version 3 -- 06-Jul-2005 - * - */ -public class CSPRNG_DO_NOT_USE extends Random implements IRandomGenerator { - - // pre-compute a few values - private static final BigInteger two = BigInteger.valueOf(2L); - - private static final BigInteger three = BigInteger.valueOf(3L); - - private static final BigInteger four = BigInteger.valueOf(4L); - - /** - * main parameter - */ - private BigInteger n; - - private BigInteger state; - - /** - * Generate appropriate prime number for use in Blum-Blum-Shub. - * - * This generates the appropriate primes (p = 3 mod 4) needed to compute the - * "n-value" for Blum-Blum-Shub. - * - * @param bits Number of bits in prime - * @param rand A source of randomness - */ - private static BigInteger getPrime(int bits, Random rand) { - BigInteger p; - while (true) { - p = new BigInteger(bits, 100, rand); - if (p.mod(four).equals(three)) - break; - } - return p; - } - - /** - * This generates the "n value" -- the multiplication of two equally sized - * random prime numbers -- for use in the Blum-Blum-Shub algorithm. - * - * @param bits - * The number of bits of security - * @param rand - * A random instance to aid in generating primes - * @return A BigInteger, the n. - */ - public static BigInteger generateN(int bits, Random rand) { - BigInteger p = getPrime(bits/2, rand); - BigInteger q = getPrime(bits/2, rand); - - // make sure p != q (almost always true, but just in case, check) - while (p.equals(q)) { - q = getPrime(bits, rand); - } - return p.multiply(q); - } - - /** - * Constructor, specifing bits for n - * - * @param bits number of bits - */ - public CSPRNG_DO_NOT_USE(int bits) { - this(bits, new Random()); - } - - /** - * Constructor, generates prime and seed - * - * @param bits - * @param rand - */ - public CSPRNG_DO_NOT_USE(int bits, Random rand) { - this(generateN(bits, rand)); - } - - /** - * A constructor to specify the "n-value" to the Blum-Blum-Shub algorithm. - * The inital seed is computed using Java's internal "true" random number - * generator. - * - * @param n - * The n-value. - */ - public CSPRNG_DO_NOT_USE(BigInteger n) { - this(n, SecureRandom.getSeed(n.bitLength() / 8)); - } - - /** - * A constructor to specify both the n-value and the seed to the - * Blum-Blum-Shub algorithm. - * - * @param n - * The n-value using a BigInteger - * @param seed - * The seed value using a byte[] array. - */ - public CSPRNG_DO_NOT_USE(BigInteger n, byte[] seed) { - this.n = n; - setSeed(seed); - } - - /** - * Sets or resets the seed value and internal state - * - * @param seedBytes - * The new seed. - */ - public void setSeed(byte[] seedBytes) { - // ADD: use hardwired default for n - BigInteger seed = new BigInteger(1, seedBytes); - state = seed.mod(n); - } - - /** - * Returns up to numBit random bits - * - * @return int - */ - @Override - public int next(int numBits) { - // TODO: find out how many LSB one can extract per cycle. - // it is more than one. - int result = 0; - for (int i = numBits; i != 0; --i) { - state = state.modPow(two, n); - result = (result << 1) | (state.testBit(0) == true ? 1 : 0); - } - return result; - } - - - public static CSPRNG_DO_NOT_USE generate(){ - return generate(512); - } - - /** - * @return CSPRNG_DO_NOT_USE - * @Author Draknyte1/Alkalus - */ - public static CSPRNG_DO_NOT_USE generate(int bitsize){ - // First use the internal, stock "true" random number - // generator to get a "true random seed" - SecureRandom r = Utils.generateSecureRandom(); - r.nextInt(); // need to do something for SR to be triggered. - // Use this seed to generate a n-value for Blum-Blum-Shub - // This value can be re-used if desired. - BigInteger nval = CSPRNG_DO_NOT_USE.generateN(bitsize, r); - // now get a seed - byte[] seed = new byte[bitsize/8]; - r.nextBytes(seed); - // now create an instance of BlumBlumShub - CSPRNG_DO_NOT_USE bbs = new CSPRNG_DO_NOT_USE(nval, seed); - return bbs; - } - - - /** - * @return CSPRNG_DO_NOT_USE - * @Author Draknyte1/Alkalus - */ - public static CSPRNG_DO_NOT_USE generate(Random aRandom){ - return generate(512, aRandom); - } - - /** - * @return CSPRNG_DO_NOT_USE - * @Author Draknyte1/Alkalus - */ - public static CSPRNG_DO_NOT_USE generate(int aBitSize, Random aRandom){ - // First use the internal, stock "true" random number - // generator to get a "true random seed" - SecureRandom r = Utils.generateSecureRandom(); - r.nextInt(); // need to do something for SR to be triggered. - // Use this seed to generate a n-value for Blum-Blum-Shub - // This value can be re-used if desired. - int bitsize = aBitSize; - // now create an instance of BlumBlumShub - // do everything almost automatically - CSPRNG_DO_NOT_USE bbs = new CSPRNG_DO_NOT_USE(bitsize, aRandom); - return bbs; - } - -} diff --git a/src/Java/gtPlusPlus/api/objects/ChunkManager.java b/src/Java/gtPlusPlus/api/objects/ChunkManager.java deleted file mode 100644 index 0bace04bf8..0000000000 --- a/src/Java/gtPlusPlus/api/objects/ChunkManager.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) CovertJaguar, 2014 http://railcraft.info - * - * This code is the property of CovertJaguar - * and may only be used with explicit written - * permission unless otherwise specified on the - * license page at http://railcraft.info/wiki/info:license. - */ -package gtPlusPlus.api.objects; - -import com.google.common.collect.LinkedListMultimap; -import com.google.common.collect.ListMultimap; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import gtPlusPlus.GTplusplus; -import gtPlusPlus.core.util.array.BlockPos; -import gtPlusPlus.core.util.array.Triplet; -import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.entity.Entity; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraftforge.common.ForgeChunkManager; -import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; -import net.minecraftforge.common.ForgeChunkManager.OrderedLoadingCallback; -import net.minecraftforge.common.ForgeChunkManager.Ticket; -import net.minecraftforge.common.ForgeChunkManager.Type; -import net.minecraftforge.event.entity.EntityEvent; - -/** - * @author CovertJaguar - */ -public class ChunkManager implements LoadingCallback, OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { - - private static ChunkManager instance; - - public static ConcurrentHashMap> mChunkLoaderManagerMap = new ConcurrentHashMap>(); - - - public static ChunkManager getInstance() { - if (instance == null) { - instance = new ChunkManager(); - } - return instance; - } - - @SubscribeEvent - public void entityEnteredChunk(EntityEvent.EnteringChunk event) { - - } - - /** - * Returns a Set of ChunkCoordIntPair containing the chunks between the - * start and end chunks. - *

- * One of the pairs of start/end coords need to be equal. - *

- * Coordinates are in chunk coordinates, not world coordinates. - * - * @param xChunkA Start Chunk x-Coord - * @param zChunkA Start Chunk z-Coord - * @param xChunkB End Chunk x-Coord - * @param zChunkB End Chunk z-Coord - * @param max Max number of chunks to return - * @return A set of chunks. - */ - public Set getChunksBetween(int xChunkA, int zChunkA, int xChunkB, int zChunkB, int max) { - Set chunkList = new HashSet(); - - if (xChunkA != xChunkB && zChunkA != zChunkB) { - return chunkList; - } - - int xStart = Math.min(xChunkA, xChunkB); - int xEnd = Math.max(xChunkA, xChunkB); - - int zStart = Math.min(zChunkA, zChunkB); - int zEnd = Math.max(zChunkA, zChunkB); - - for (int xx = xStart; xx <= xEnd; xx++) { - for (int zz = zStart; zz <= zEnd; zz++) { - chunkList.add(new ChunkCoordIntPair(xx, zz)); - if (chunkList.size() >= max) { - return chunkList; - } - } - } - return chunkList; - } - - /** - * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, - * z]. Coordinates are in chunk coordinates, not world coordinates. - * - * @param xChunk Chunk x-Coord - * @param zChunk Chunk z-Coord - * @param radius Distance from [x, z] to include, in number of chunks. - * @return A set of chunks. - */ - public Set getChunksAround(int xChunk, int zChunk, int radius) { - Set chunkList = new HashSet(); - for (int xx = xChunk - radius; xx <= xChunk + radius; xx++) { - for (int zz = zChunk - radius; zz <= zChunk + radius; zz++) { - chunkList.add(new ChunkCoordIntPair(xx, zz)); - } - } - return chunkList; - } - - /** - * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, - * z]. Coordinates are in world coordinates, not chunk coordinates. - * - * @param xWorld World x-Coord - * @param zWorld World z-Coord - * @param radius Distance from [x, z] to include, in blocks. - * @return A set of chunks. - */ - public Set getBufferAround(int xWorld, int zWorld, int radius) { - int minX = (xWorld - radius) >> 4; - int maxX = (xWorld + radius) >> 4; - int minZ = (zWorld - radius) >> 4; - int maxZ = (zWorld + radius) >> 4; - - Set chunkList = new HashSet(); - for (int xx = minX; xx <= maxX; xx++) { - for (int zz = minZ; zz <= maxZ; zz++) { - chunkList.add(new ChunkCoordIntPair(xx, zz)); - } - } - return chunkList; - } - - private void printAnchor(String type, int x, int y, int z) { - Logger.INFO("[Chunk Loader] "+type+" @ [x: "+x+"][y: "+y+"][z: "+z+"]"); - } - - @Override - public void ticketsLoaded(List tickets, World world) { - - if (world.isRemote) return; - - // System.out.println("Callback 2"); - for (Ticket ticket : tickets) { - if (ticket.isPlayerTicket()) - continue; - Entity entity = ticket.getEntity(); - if (entity == null) { - int x = ticket.getModData().getInteger("xCoord"); - int y = ticket.getModData().getInteger("yCoord"); - int z = ticket.getModData().getInteger("zCoord"); - - if (y >= 0) { - BlockPos tile = new BlockPos(x, y, z); - - Ticket H = tryForceLoadChunk(new DimChunkPos(world, tile).getChunk()); - - int jhg = 0; - while (jhg < 50) { - jhg++; - } - - if (!mChunkLoaderManagerMap.isEmpty()) { - GregtechMetaTileEntityChunkLoader f = mChunkLoaderManagerMap.get(tile).getValue_2(); - int timeout = 0; - while (f == null) { - if (timeout > 5000) { - Logger.INFO("[Chunk Loader] Timed out"); - break; - } - else { - GregtechMetaTileEntityChunkLoader g; - if (!mChunkLoaderManagerMap.isEmpty()) { - g = mChunkLoaderManagerMap.get(tile).getValue_2(); - if (g == null) { - timeout++; - } - else { - Logger.INFO("[Chunk Loader]Tile became Valid"); - f = g; - break; - } - } - } - } - try { - if (f != null) { - - - if (H != null) { - ForgeChunkManager.releaseTicket(H); - } - - f.forceChunkLoading(ticket); - printAnchor("Force Chunk Loading. Chunk Loader has ID of "+f.getLoaderID()+". ",x,y,z); - } - else { - Logger.INFO("Tile Entity is null."); - } - } - catch (Throwable t) { - t.printStackTrace(); - Logger.INFO("Mild problem with chunk loading, nothing to worry about."); - } - - - if (H != null) { - ForgeChunkManager.releaseTicket(H); - } - - } - - /*if (tile instanceof IGregTechTileEntity) { - final IGregTechTileEntity tGregTechTileEntity = (IGregTechTileEntity) tile; - IGregTechTileEntity anchor = (IGregTechTileEntity) tile; - GregtechMetaTileEntityChunkLoader jun = (GregtechMetaTileEntityChunkLoader) anchor; - jun.forceChunkLoading(ticket); - //printAnchor(anchor.getName(), x, y, z); - }*/ - } - } - } - } - - @Override - public List ticketsLoaded(List tickets, World world, int maxTicketCount) { - // System.out.println("Callback 1"); - Set adminTickets = new HashSet(); - Set worldTickets = new HashSet(); - Set cartTickets = new HashSet(); - for (Ticket ticket : tickets) { - Entity entity = ticket.getEntity(); - if (entity == null) { - int x = ticket.getModData().getInteger("xCoord"); - int y = ticket.getModData().getInteger("yCoord"); - int z = ticket.getModData().getInteger("zCoord"); - if (y >= 0) { - worldTickets.add(ticket); - } - } - } - - List claimedTickets = new LinkedList(); - claimedTickets.addAll(cartTickets); - claimedTickets.addAll(adminTickets); - claimedTickets.addAll(worldTickets); - return claimedTickets; - } - - @Override - public ListMultimap playerTicketsLoaded(ListMultimap tickets, World world) { - return LinkedListMultimap.create(); - } - - - public static Timer createChunkQueue() { - return ChunkTimerLoader(); - } - - public static Ticket tryForceLoadChunk(Chunk c) { - Ticket T = getTicketFromForge(c.worldObj); - ForgeChunkManager.forceChunk(T, c.getChunkCoordIntPair()); - Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); - return T; - } - - public static Ticket getTicketFromForge(World world) { - return ForgeChunkManager.requestTicket(GTplusplus.instance, world, Type.NORMAL); - } - - static Timer ChunkTimerLoader() { - Timer timer; - timer = new Timer(); - timer.schedule(new ChunkCache(), 10 * 1000); - return timer; - } - - //Timer Task for notifying the player. - static class ChunkCache extends TimerTask { - public ChunkCache() { - - } - - @Override - public void run() { - if (mChunkLoaderManagerMap.size() > 0) { - for (Triplet j : mChunkLoaderManagerMap.values()) { - Ticket T; - Chunk C; - T = j.getValue_2().getTicketFromForge(); - C = j.getValue_3().getChunk(); - ForgeChunkManager.forceChunk(T, C.getChunkCoordIntPair()); - Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); - } - } - else { - Logger.INFO("[Chunk Loader] No chunks to try to force load chunks that hold chunkloaders."); - } - } - } -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/DimChunkPos.java b/src/Java/gtPlusPlus/api/objects/DimChunkPos.java deleted file mode 100644 index bea0a4ec3b..0000000000 --- a/src/Java/gtPlusPlus/api/objects/DimChunkPos.java +++ /dev/null @@ -1,53 +0,0 @@ -package gtPlusPlus.api.objects; - -import gtPlusPlus.core.util.array.BlockPos; -import net.minecraft.client.Minecraft; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; - -public class DimChunkPos { - - public final int dimension; - public final int xPos; - public final int zPos; - public final Chunk mainChunk; - - - public DimChunkPos(World world, BlockPos block){ - this.dimension = world.provider.dimensionId; - this.mainChunk = world.getChunkFromBlockCoords(block.xPos, block.zPos); - this.xPos = this.mainChunk.xPosition; - this.zPos = this.mainChunk.zPosition; - } - - - public DimChunkPos(TileEntity tile){ - this.dimension = tile.getWorldObj().provider.dimensionId; - this.mainChunk = tile.getWorldObj().getChunkFromBlockCoords(tile.xCoord, tile.zCoord); - this.xPos = this.mainChunk.xPosition; - this.zPos = this.mainChunk.zPosition; - } - - public DimChunkPos(int dim, int x, int z){ - this.dimension = dim; - this.xPos = x; - this.zPos = z; - Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(dim).getChunkFromChunkCoords(xPos, zPos); - if (h == null) { - this.mainChunk = null; - } - else { - this.mainChunk = h; - } - } - - public Chunk getChunk() { - if (this.mainChunk != null) { - return this.mainChunk; - } - Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(this.dimension).getChunkFromChunkCoords(xPos, zPos); - return h; - } - -} diff --git a/src/Java/gtPlusPlus/api/objects/GenericStack.java b/src/Java/gtPlusPlus/api/objects/GenericStack.java deleted file mode 100644 index b3bc94364f..0000000000 --- a/src/Java/gtPlusPlus/api/objects/GenericStack.java +++ /dev/null @@ -1,41 +0,0 @@ -package gtPlusPlus.api.objects; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -public class GenericStack { - - private ItemStack mItemStack; - private FluidStack mFluidStack; - - public GenericStack(ItemStack s){ - this.mItemStack = s; - this.mFluidStack = null; - } - - public GenericStack(FluidStack f){ - this.mItemStack = null; - this.mFluidStack = f; - } - - public GenericStack() { - this.mItemStack = null; - this.mFluidStack = null; - } - - public synchronized final FluidStack getFluidStack() { - return mFluidStack; - } - - public synchronized final ItemStack getItemStack() { - return mItemStack; - } - - public synchronized final void setItemStack(ItemStack mItemStack) { - this.mItemStack = mItemStack; - } - - public synchronized final void setFluidStack(FluidStack mFluidStack) { - this.mFluidStack = mFluidStack; - } -} diff --git a/src/Java/gtPlusPlus/api/objects/MaterialHelper.java b/src/Java/gtPlusPlus/api/objects/MaterialHelper.java deleted file mode 100644 index d63ab7a15a..0000000000 --- a/src/Java/gtPlusPlus/api/objects/MaterialHelper.java +++ /dev/null @@ -1,18 +0,0 @@ -package gtPlusPlus.api.objects; - -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gtPlusPlus.core.material.Material; -import gtPlusPlus.core.util.item.ItemUtils; -import net.minecraft.item.ItemStack; - -public class MaterialHelper { - - public static ItemStack getComponentFromMaterial(OrePrefixes oreprefix, Material material, int amount){ - return ItemUtils.getOrePrefixStack(oreprefix, material, amount); - } - public static ItemStack getComponentFromGtMaterial(OrePrefixes oreprefix, Materials material, int amount){ - return ItemUtils.getGregtechOreStack(oreprefix, material, amount); - } - -} diff --git a/src/Java/gtPlusPlus/api/objects/XSTR.java b/src/Java/gtPlusPlus/api/objects/XSTR.java deleted file mode 100644 index 3ff0792f6e..0000000000 --- a/src/Java/gtPlusPlus/api/objects/XSTR.java +++ /dev/null @@ -1,266 +0,0 @@ -package gtPlusPlus.api.objects; -/** - * A subclass of java.util.random that implements the Xorshift random number - * generator - * - * - it is 30% faster than the generator from Java's library - it produces - * random sequences of higher quality than java.util.Random - this class also - * provides a clone() function - * - * Usage: XSRandom rand = new XSRandom(); //Instantiation x = rand.nextInt(); - * //pull a random number - * - * To use the class in legacy code, you may also instantiate an XSRandom object - * and assign it to a java.util.Random object: java.util.Random rand = new - * XSRandom(); - * - * for an explanation of the algorithm, see - * http://demesos.blogspot.com/2011/09/pseudo-random-number-generators.html - * - * @author Wilfried Elmenreich University of Klagenfurt/Lakeside Labs - * http://www.elmenreich.tk - * - * This code is released under the GNU Lesser General Public License Version 3 - * http://www.gnu.org/licenses/lgpl-3.0.txt - */ - -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -/** - * XSTR - Xorshift ThermiteRandom - * Modified by Bogdan-G - * 03.06.2016 - * version 0.0.4 - */ -public class XSTR extends Random { - - private static final long serialVersionUID = 6208727693524452904L; - private long seed; - private long last; - private static final long GAMMA = 0x9e3779b97f4a7c15L; - private static final int PROBE_INCREMENT = 0x9e3779b9; - private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL; - private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) - private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24) - - /* - MODIFIED BY: Robotia - Modification: Implemented Random class seed generator - */ - /** - * Creates a new pseudo random number generator. The seed is initialized to - * the current time, as if by - * setSeed(System.currentTimeMillis());. - */ - public XSTR() { - this(seedUniquifier() ^ System.nanoTime()); - } - private static final AtomicLong seedUniquifier - = new AtomicLong(8682522807148012L); - - private static long seedUniquifier() { - // L'Ecuyer, "Tables of Linear Congruential Generators of - // Different Sizes and Good Lattice Structure", 1999 - for (;;) { - final long current = seedUniquifier.get(); - final long next = current * 181783497276652981L; - if (seedUniquifier.compareAndSet(current, next)) { - return next; - } - } - } - - /** - * Creates a new pseudo random number generator, starting with the specified - * seed, using setSeed(seed);. - * - * @param seed the initial seed - */ - public XSTR(final long seed) { - this.seed = seed; - } - @Override - public boolean nextBoolean() { - return this.next(1) != 0; - } - - @Override - public double nextDouble() { - return (((long)(this.next(26)) << 27) + this.next(27)) * DOUBLE_UNIT; - } - /** - * Returns the current state of the seed, can be used to clone the object - * - * @return the current seed - */ - public synchronized long getSeed() { - return this.seed; - } - - /** - * Sets the seed for this pseudo random number generator. As described - * above, two instances of the same random class, starting with the same - * seed, produce the same results, if the same methods are called. - * - * @param seed the new seed - */ - @Override - public synchronized void setSeed(final long seed) { - this.seed = seed; - } - - /** - * @return Returns an XSRandom object with the same state as the original - */ - @Override - public XSTR clone() { - return new XSTR(this.getSeed()); - } - - /** - * Implementation of George Marsaglia's elegant Xorshift random generator - * 30% faster and better quality than the built-in java.util.random see also - * see http://www.javamex.com/tutorials/random_numbers/xorshift.shtml - * - * @param nbits - * @return - */ - @Override - public int next(final int nbits) { - long x = this.seed; - x ^= (x << 21); - x ^= (x >>> 35); - x ^= (x << 4); - this.seed = x; - x &= ((1L << nbits) - 1); - return (int) x; - } - boolean haveNextNextGaussian = false; - double nextNextGaussian = 0; - @Override - synchronized public double nextGaussian() { - // See Knuth, ACP, Section 3.4.1 Algorithm C. - if (this.haveNextNextGaussian) { - this.haveNextNextGaussian = false; - return this.nextNextGaussian; - } - double v1, v2, s; - do { - v1 = (2 * this.nextDouble()) - 1; // between -1 and 1 - v2 = (2 * this.nextDouble()) - 1; // between -1 and 1 - s = (v1 * v1) + (v2 * v2); - } while ((s >= 1) || (s == 0)); - final double multiplier = StrictMath.sqrt((-2 * StrictMath.log(s))/s); - this.nextNextGaussian = v2 * multiplier; - this.haveNextNextGaussian = true; - return v1 * multiplier; - } - /** - * Returns a pseudorandom, uniformly distributed {@code int} value between 0 - * (inclusive) and the specified value (exclusive), drawn from this random - * number generator's sequence. The general contract of {@code nextInt} is - * that one {@code int} value in the specified range is pseudorandomly - * generated and returned. All {@code bound} possible {@code int} values are - * produced with (approximately) equal probability. The method - * {@code nextInt(int bound)} is implemented by class {@code Random} as if - * by: - *

 {@code
-	 * public int nextInt(int bound) {
-	 *   if (bound <= 0)
-	 *     throw new IllegalArgumentException("bound must be positive");
-	 *
-	 *   if ((bound & -bound) == bound)  // i.e., bound is a power of 2
-	 *     return (int)((bound * (long)next(31)) >> 31);
-	 *
-	 *   int bits, val;
-	 *   do {
-	 *       bits = next(31);
-	 *       val = bits % bound;
-	 *   } while (bits - val + (bound-1) < 0);
-	 *   return val;
-	 * }}
- * - *

The hedge "approx - * imately" is used in the foregoing description only because the next - * method is only approximately an unbiased source of independently chosen - * bits. If it were a perfect source of randomly chosen bits, then the - * algorithm shown would choose {@code int} values from the stated range - * with perfect uniformity. - *

- * The algorithm is slightly tricky. It rejects values that would result in - * an uneven distribution (due to the fact that 2^31 is not divisible by n). - * The probability of a value being rejected depends on n. The worst case is - * n=2^30+1, for which the probability of a reject is 1/2, and the expected - * number of iterations before the loop terminates is 2. - *

- * The algorithm treats the case where n is a power of two specially: it - * returns the correct number of high-order bits from the underlying - * pseudo-random number generator. In the absence of special treatment, the - * correct number of low-order bits would be returned. Linear - * congruential pseudo-random number generators such as the one implemented - * by this class are known to have short periods in the sequence of values - * of their low-order bits. Thus, this special case greatly increases the - * length of the sequence of values returned by successive calls to this - * method if n is a small power of two. - * - * @param bound the upper bound (exclusive). Must be positive. - * @return the next pseudorandom, uniformly distributed {@code int} value - * between zero (inclusive) and {@code bound} (exclusive) from this random - * number generator's sequence - * @throws IllegalArgumentException if bound is not positive - * @since 1.2 - */ - @Override - public int nextInt(final int bound) { - //if (bound <= 0) { - //throw new RuntimeException("BadBound"); - //} - - /*int r = next(31); - int m = bound - 1; - if ((bound & m) == 0) // i.e., bound is a power of 2 - { - r = (int) ((bound * (long) r) >> 31); - } else { - for (int u = r; - u - (r = u % bound) + m < 0; - u = next(31)) - ; - } - return r;*/ - //speedup, new nextInt ~+40% - this.last = this.seed ^ (this.seed << 21); - this.last ^= (this.last >>> 35); - this.last ^= (this.last << 4); - this.seed = this.last; - final int out = (int) this.last % bound; - return (out < 0) ? -out : out; - } - @Override - public int nextInt() { - return this.next(32); - } - - @Override - public float nextFloat() { - return this.next(24) * FLOAT_UNIT; - } - - @Override - public long nextLong() { - // it's okay that the bottom word remains signed. - return ((long)(this.next(32)) << 32) + this.next(32); - } - - @Override - public void nextBytes(final byte[] bytes_arr) { - for (int iba = 0, lenba = bytes_arr.length; iba < lenba; ) { - for (int rndba = this.nextInt(), - nba = Math.min(lenba - iba, Integer.SIZE/Byte.SIZE); - nba-- > 0; rndba >>= Byte.SIZE) { - bytes_arr[iba++] = (byte)rndba; - } - } - } -} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/data/AutoMap.java b/src/Java/gtPlusPlus/api/objects/data/AutoMap.java new file mode 100644 index 0000000000..a8d24d36d8 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/AutoMap.java @@ -0,0 +1,77 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; +import java.util.*; + +public class AutoMap implements Iterable, Cloneable, Serializable { + + /** + * The Internal Map + */ + private Map mInternalMap = new HashMap(); + + /** + * The Internal ID + */ + private int mInternalID = 0; + private static final long serialVersionUID = 3771412318075131790L; + + @Override + public Iterator iterator() { + return values().iterator(); + } + + public synchronized boolean setValue(V object){ + int mOriginalID = this.mInternalID; + put(object); + if (this.mInternalMap.get(mOriginalID).equals(object) || mOriginalID > this.mInternalID){ + return true; + } + else { + return false; + } + } + + public synchronized V put(V object){ + return set(object); + } + + public synchronized V set(V object){ + return mInternalMap.put(mInternalID++, object); + } + + public synchronized V get(int id){ + return mInternalMap.get(id); + } + + public synchronized Collection values(){ + return mInternalMap.values(); + } + + public synchronized int size(){ + return mInternalMap.size(); + } + + public synchronized int hashcode(){ + return mInternalMap.hashCode(); + } + + public synchronized boolean containsKey(int key){ + return mInternalMap.containsKey(key); + } + + public synchronized boolean containsValue(V value){ + return mInternalMap.containsValue(value); + } + + public synchronized boolean isEmpty(){ + return mInternalMap.isEmpty(); + } + + public synchronized boolean clear(){ + this.mInternalID = 0; + this.mInternalMap.clear(); + return true; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/data/Pair.java b/src/Java/gtPlusPlus/api/objects/data/Pair.java new file mode 100644 index 0000000000..6ab781cf1e --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Pair.java @@ -0,0 +1,27 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; + +public class Pair implements Serializable { + + /** + * SVUID + */ + private static final long serialVersionUID = 1250550491092812443L; + private final K key; + private final V value; + + public Pair(final K key, final V value){ + this.key = key; + this.value = value; + } + + final public K getKey(){ + return this.key; + } + + final public V getValue(){ + return this.value; + } + +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/data/Quad.java b/src/Java/gtPlusPlus/api/objects/data/Quad.java new file mode 100644 index 0000000000..01c62e95e6 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Quad.java @@ -0,0 +1,33 @@ +package gtPlusPlus.api.objects.data; + +public class Quad { + + private final K key; + private final V value; + private final C value2; + private final R value3; + + public Quad(final K key, final V value, final C value2, final R value3){ + this.key = key; + this.value = value; + this.value2 = value2; + this.value3 = value3; + } + + final public K getKey(){ + return this.key; + } + + final public V getValue_1(){ + return this.value; + } + + final public C getValue_2(){ + return this.value2; + } + + final public R getValue_3(){ + return this.value3; + } + +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/data/Triplet.java b/src/Java/gtPlusPlus/api/objects/data/Triplet.java new file mode 100644 index 0000000000..affb03d868 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Triplet.java @@ -0,0 +1,27 @@ +package gtPlusPlus.api.objects.data; + +public class Triplet { + + private final K key; + private final V value; + private final C count; + + public Triplet(final K key, final V value, final C value2){ + this.key = key; + this.value = value; + this.count = value2; + } + + final public K getValue_1(){ + return this.key; + } + + final public V getValue_2(){ + return this.value; + } + + final public C getValue_3(){ + return this.count; + } + +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java new file mode 100644 index 0000000000..d258d1fe73 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java @@ -0,0 +1,85 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.io.Serializable; + +public class BlockPos implements Serializable{ + + private static final long serialVersionUID = -7271947491316682006L; + public final int xPos; + public final int yPos; + public final int zPos; + public final int dim; + + public BlockPos(int x, int y, int z){ + this(x, y, z, 0); + } + + public BlockPos(int x, int y, int z, int dim){ + this.xPos = x; + this.yPos = y; + this.zPos = z; + this.dim = dim; + } + + public String getLocationString() { + return "[X: "+this.xPos+"][Y: "+this.yPos+"][Z: "+this.zPos+"][Dim: "+this.dim+"]"; + } + + @Override + public int hashCode() { + int hash = 5; + hash += (13 * this.xPos); + hash += (19 * this.yPos); + hash += (31 * this.zPos); + hash += (17 * this.dim); + return hash; + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other == this) { + return true; + } + if(!(other instanceof BlockPos)) { + return false; + } + BlockPos otherPoint = (BlockPos)other; + return this.xPos == otherPoint.xPos && this.yPos == otherPoint.yPos && this.zPos == otherPoint.zPos && this.dim == otherPoint.dim; + } + + public int distanceFrom(BlockPos target) { + if (target.dim != this.dim) { + return Short.MIN_VALUE; + } + return distanceFrom(target.xPos, target.yPos, target.zPos); + } + + /** + * + * @param x X coordinate of target. + * @param y Y coordinate of target. + * @param z Z coordinate of target. + * @return square of distance + */ + public int distanceFrom(int x, int y, int z) { + int distanceX = this.xPos - x; + int distanceY = this.yPos - y; + int distanceZ = this.zPos - z; + return distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ; + } + + public boolean isWithinRange(BlockPos target, int range) { + if (target.dim != this.dim) { + return false; + } + return isWithinRange(target.xPos, target.yPos, target.zPos, range); + } + + public boolean isWithinRange(int x, int y, int z, int range) { + return distanceFrom(x, y, z) <= (range * range); + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java new file mode 100644 index 0000000000..b411e8875a --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) CovertJaguar, 2014 http://railcraft.info + * + * This code is the property of CovertJaguar + * and may only be used with explicit written + * permission unless otherwise specified on the + * license page at http://railcraft.info/wiki/info:license. + */ +package gtPlusPlus.api.objects.minecraft; + +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.ListMultimap; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gtPlusPlus.GTplusplus; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.Triplet; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; +import net.minecraftforge.common.ForgeChunkManager.OrderedLoadingCallback; +import net.minecraftforge.common.ForgeChunkManager.Ticket; +import net.minecraftforge.common.ForgeChunkManager.Type; +import net.minecraftforge.event.entity.EntityEvent; + +/** + * @author CovertJaguar + */ +public class ChunkManager implements LoadingCallback, OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { + + private static ChunkManager instance; + + public static ConcurrentHashMap> mChunkLoaderManagerMap = new ConcurrentHashMap>(); + + + public static ChunkManager getInstance() { + if (instance == null) { + instance = new ChunkManager(); + } + return instance; + } + + @SubscribeEvent + public void entityEnteredChunk(EntityEvent.EnteringChunk event) { + + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks between the + * start and end chunks. + *

+ * One of the pairs of start/end coords need to be equal. + *

+ * Coordinates are in chunk coordinates, not world coordinates. + * + * @param xChunkA Start Chunk x-Coord + * @param zChunkA Start Chunk z-Coord + * @param xChunkB End Chunk x-Coord + * @param zChunkB End Chunk z-Coord + * @param max Max number of chunks to return + * @return A set of chunks. + */ + public Set getChunksBetween(int xChunkA, int zChunkA, int xChunkB, int zChunkB, int max) { + Set chunkList = new HashSet(); + + if (xChunkA != xChunkB && zChunkA != zChunkB) { + return chunkList; + } + + int xStart = Math.min(xChunkA, xChunkB); + int xEnd = Math.max(xChunkA, xChunkB); + + int zStart = Math.min(zChunkA, zChunkB); + int zEnd = Math.max(zChunkA, zChunkB); + + for (int xx = xStart; xx <= xEnd; xx++) { + for (int zz = zStart; zz <= zEnd; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + if (chunkList.size() >= max) { + return chunkList; + } + } + } + return chunkList; + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, + * z]. Coordinates are in chunk coordinates, not world coordinates. + * + * @param xChunk Chunk x-Coord + * @param zChunk Chunk z-Coord + * @param radius Distance from [x, z] to include, in number of chunks. + * @return A set of chunks. + */ + public Set getChunksAround(int xChunk, int zChunk, int radius) { + Set chunkList = new HashSet(); + for (int xx = xChunk - radius; xx <= xChunk + radius; xx++) { + for (int zz = zChunk - radius; zz <= zChunk + radius; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + } + } + return chunkList; + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, + * z]. Coordinates are in world coordinates, not chunk coordinates. + * + * @param xWorld World x-Coord + * @param zWorld World z-Coord + * @param radius Distance from [x, z] to include, in blocks. + * @return A set of chunks. + */ + public Set getBufferAround(int xWorld, int zWorld, int radius) { + int minX = (xWorld - radius) >> 4; + int maxX = (xWorld + radius) >> 4; + int minZ = (zWorld - radius) >> 4; + int maxZ = (zWorld + radius) >> 4; + + Set chunkList = new HashSet(); + for (int xx = minX; xx <= maxX; xx++) { + for (int zz = minZ; zz <= maxZ; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + } + } + return chunkList; + } + + private void printAnchor(String type, int x, int y, int z) { + Logger.INFO("[Chunk Loader] "+type+" @ [x: "+x+"][y: "+y+"][z: "+z+"]"); + } + + @Override + public void ticketsLoaded(List tickets, World world) { + + if (world.isRemote) return; + + // System.out.println("Callback 2"); + for (Ticket ticket : tickets) { + if (ticket.isPlayerTicket()) + continue; + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + + if (y >= 0) { + BlockPos tile = new BlockPos(x, y, z); + + Ticket H = tryForceLoadChunk(new DimChunkPos(world, tile).getChunk()); + + int jhg = 0; + while (jhg < 50) { + jhg++; + } + + if (!mChunkLoaderManagerMap.isEmpty()) { + GregtechMetaTileEntityChunkLoader f = mChunkLoaderManagerMap.get(tile).getValue_2(); + int timeout = 0; + while (f == null) { + if (timeout > 5000) { + Logger.INFO("[Chunk Loader] Timed out"); + break; + } + else { + GregtechMetaTileEntityChunkLoader g; + if (!mChunkLoaderManagerMap.isEmpty()) { + g = mChunkLoaderManagerMap.get(tile).getValue_2(); + if (g == null) { + timeout++; + } + else { + Logger.INFO("[Chunk Loader]Tile became Valid"); + f = g; + break; + } + } + } + } + try { + if (f != null) { + + + if (H != null) { + ForgeChunkManager.releaseTicket(H); + } + + f.forceChunkLoading(ticket); + printAnchor("Force Chunk Loading. Chunk Loader has ID of "+f.getLoaderID()+". ",x,y,z); + } + else { + Logger.INFO("Tile Entity is null."); + } + } + catch (Throwable t) { + t.printStackTrace(); + Logger.INFO("Mild problem with chunk loading, nothing to worry about."); + } + + + if (H != null) { + ForgeChunkManager.releaseTicket(H); + } + + } + + /*if (tile instanceof IGregTechTileEntity) { + final IGregTechTileEntity tGregTechTileEntity = (IGregTechTileEntity) tile; + IGregTechTileEntity anchor = (IGregTechTileEntity) tile; + GregtechMetaTileEntityChunkLoader jun = (GregtechMetaTileEntityChunkLoader) anchor; + jun.forceChunkLoading(ticket); + //printAnchor(anchor.getName(), x, y, z); + }*/ + } + } + } + } + + @Override + public List ticketsLoaded(List tickets, World world, int maxTicketCount) { + // System.out.println("Callback 1"); + Set adminTickets = new HashSet(); + Set worldTickets = new HashSet(); + Set cartTickets = new HashSet(); + for (Ticket ticket : tickets) { + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + if (y >= 0) { + worldTickets.add(ticket); + } + } + } + + List claimedTickets = new LinkedList(); + claimedTickets.addAll(cartTickets); + claimedTickets.addAll(adminTickets); + claimedTickets.addAll(worldTickets); + return claimedTickets; + } + + @Override + public ListMultimap playerTicketsLoaded(ListMultimap tickets, World world) { + return LinkedListMultimap.create(); + } + + + public static Timer createChunkQueue() { + return ChunkTimerLoader(); + } + + public static Ticket tryForceLoadChunk(Chunk c) { + Ticket T = getTicketFromForge(c.worldObj); + ForgeChunkManager.forceChunk(T, c.getChunkCoordIntPair()); + Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); + return T; + } + + public static Ticket getTicketFromForge(World world) { + return ForgeChunkManager.requestTicket(GTplusplus.instance, world, Type.NORMAL); + } + + static Timer ChunkTimerLoader() { + Timer timer; + timer = new Timer(); + timer.schedule(new ChunkCache(), 10 * 1000); + return timer; + } + + //Timer Task for notifying the player. + static class ChunkCache extends TimerTask { + public ChunkCache() { + + } + + @Override + public void run() { + if (mChunkLoaderManagerMap.size() > 0) { + for (Triplet j : mChunkLoaderManagerMap.values()) { + Ticket T; + Chunk C; + T = j.getValue_2().getTicketFromForge(); + C = j.getValue_3().getChunk(); + ForgeChunkManager.forceChunk(T, C.getChunkCoordIntPair()); + Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); + } + } + else { + Logger.INFO("[Chunk Loader] No chunks to try to force load chunks that hold chunkloaders."); + } + } + } +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java new file mode 100644 index 0000000000..010e522a14 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java @@ -0,0 +1,52 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.client.Minecraft; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; + +public class DimChunkPos { + + public final int dimension; + public final int xPos; + public final int zPos; + public final Chunk mainChunk; + + + public DimChunkPos(World world, BlockPos block){ + this.dimension = world.provider.dimensionId; + this.mainChunk = world.getChunkFromBlockCoords(block.xPos, block.zPos); + this.xPos = this.mainChunk.xPosition; + this.zPos = this.mainChunk.zPosition; + } + + + public DimChunkPos(TileEntity tile){ + this.dimension = tile.getWorldObj().provider.dimensionId; + this.mainChunk = tile.getWorldObj().getChunkFromBlockCoords(tile.xCoord, tile.zCoord); + this.xPos = this.mainChunk.xPosition; + this.zPos = this.mainChunk.zPosition; + } + + public DimChunkPos(int dim, int x, int z){ + this.dimension = dim; + this.xPos = x; + this.zPos = z; + Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(dim).getChunkFromChunkCoords(xPos, zPos); + if (h == null) { + this.mainChunk = null; + } + else { + this.mainChunk = h; + } + } + + public Chunk getChunk() { + if (this.mainChunk != null) { + return this.mainChunk; + } + Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(this.dimension).getChunkFromChunkCoords(xPos, zPos); + return h; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java new file mode 100644 index 0000000000..f5db1d9e3a --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java @@ -0,0 +1,41 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class GenericStack { + + private ItemStack mItemStack; + private FluidStack mFluidStack; + + public GenericStack(ItemStack s){ + this.mItemStack = s; + this.mFluidStack = null; + } + + public GenericStack(FluidStack f){ + this.mItemStack = null; + this.mFluidStack = f; + } + + public GenericStack() { + this.mItemStack = null; + this.mFluidStack = null; + } + + public synchronized final FluidStack getFluidStack() { + return mFluidStack; + } + + public synchronized final ItemStack getItemStack() { + return mItemStack; + } + + public synchronized final void setItemStack(ItemStack mItemStack) { + this.mItemStack = mItemStack; + } + + public synchronized final void setFluidStack(FluidStack mFluidStack) { + this.mFluidStack = mFluidStack; + } +} diff --git a/src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java b/src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java new file mode 100644 index 0000000000..b2dc984456 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java @@ -0,0 +1,271 @@ +/* + * Copyright 2005, Nick Galbreath -- nickg [at] modp [dot] com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of the modp.com nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is the standard "new" BSD license: + * http://www.opensource.org/licenses/bsd-license.php + */ + +package gtPlusPlus.api.objects.random; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Random; + +import gtPlusPlus.api.interfaces.IRandomGenerator; +import gtPlusPlus.core.util.Utils; + +/** + * The Blum-Blum-Shub random number generator. + * + *

+ * The Blum-Blum-Shub is a "cryptographically secure" random number + * generator. It has been proven that predicting the ouput + * is equivalent to factoring n, a large integer generated + * from two prime numbers. + *

+ * + *

+ * The Algorithm: + *

+ *
    + *
  1. + * (setup) generate two secret prime numbers p, q such that + * pq, p ≡ 3 mod 4, q ≡ 3 mod 4. + *
  2. + *
  3. (setup) compute n = pq. n can be re-used, but + * p, and q are secret and should be disposed of.
  4. + *
  5. Generate a (secure) random seed s in the range [1, n -1] + * such that gcd(s, n) = 1. + *
  6. Compute x = s2 mod n
  7. + *
  8. Compute a single random bit with: + *
      + *
    1. x = x2 mod n
    2. + *
    3. return Least-Significant-Bit(x) (i.e. x & 1)
    4. + *
    + * Repeat as necessary. + *
  9. + *
+ * + *

+ * The code originally appeared in Cryptography for + * Internet and Database Applications , Chapter 4, pages 174-177 + *

+ *

+ * More details are in the Handbook of Applied Cryptography, + * Section 5.5.2 + *

+ * + * @author Nick Galbreath -- nickg [at] modp [dot] com + * @version 3 -- 06-Jul-2005 + * + */ +public class CSPRNG_DO_NOT_USE extends Random implements IRandomGenerator { + + // pre-compute a few values + private static final BigInteger two = BigInteger.valueOf(2L); + + private static final BigInteger three = BigInteger.valueOf(3L); + + private static final BigInteger four = BigInteger.valueOf(4L); + + /** + * main parameter + */ + private BigInteger n; + + private BigInteger state; + + /** + * Generate appropriate prime number for use in Blum-Blum-Shub. + * + * This generates the appropriate primes (p = 3 mod 4) needed to compute the + * "n-value" for Blum-Blum-Shub. + * + * @param bits Number of bits in prime + * @param rand A source of randomness + */ + private static BigInteger getPrime(int bits, Random rand) { + BigInteger p; + while (true) { + p = new BigInteger(bits, 100, rand); + if (p.mod(four).equals(three)) + break; + } + return p; + } + + /** + * This generates the "n value" -- the multiplication of two equally sized + * random prime numbers -- for use in the Blum-Blum-Shub algorithm. + * + * @param bits + * The number of bits of security + * @param rand + * A random instance to aid in generating primes + * @return A BigInteger, the n. + */ + public static BigInteger generateN(int bits, Random rand) { + BigInteger p = getPrime(bits/2, rand); + BigInteger q = getPrime(bits/2, rand); + + // make sure p != q (almost always true, but just in case, check) + while (p.equals(q)) { + q = getPrime(bits, rand); + } + return p.multiply(q); + } + + /** + * Constructor, specifing bits for n + * + * @param bits number of bits + */ + public CSPRNG_DO_NOT_USE(int bits) { + this(bits, new Random()); + } + + /** + * Constructor, generates prime and seed + * + * @param bits + * @param rand + */ + public CSPRNG_DO_NOT_USE(int bits, Random rand) { + this(generateN(bits, rand)); + } + + /** + * A constructor to specify the "n-value" to the Blum-Blum-Shub algorithm. + * The inital seed is computed using Java's internal "true" random number + * generator. + * + * @param n + * The n-value. + */ + public CSPRNG_DO_NOT_USE(BigInteger n) { + this(n, SecureRandom.getSeed(n.bitLength() / 8)); + } + + /** + * A constructor to specify both the n-value and the seed to the + * Blum-Blum-Shub algorithm. + * + * @param n + * The n-value using a BigInteger + * @param seed + * The seed value using a byte[] array. + */ + public CSPRNG_DO_NOT_USE(BigInteger n, byte[] seed) { + this.n = n; + setSeed(seed); + } + + /** + * Sets or resets the seed value and internal state + * + * @param seedBytes + * The new seed. + */ + public void setSeed(byte[] seedBytes) { + // ADD: use hardwired default for n + BigInteger seed = new BigInteger(1, seedBytes); + state = seed.mod(n); + } + + /** + * Returns up to numBit random bits + * + * @return int + */ + @Override + public int next(int numBits) { + // TODO: find out how many LSB one can extract per cycle. + // it is more than one. + int result = 0; + for (int i = numBits; i != 0; --i) { + state = state.modPow(two, n); + result = (result << 1) | (state.testBit(0) == true ? 1 : 0); + } + return result; + } + + + public static CSPRNG_DO_NOT_USE generate(){ + return generate(512); + } + + /** + * @return CSPRNG_DO_NOT_USE + * @Author Draknyte1/Alkalus + */ + public static CSPRNG_DO_NOT_USE generate(int bitsize){ + // First use the internal, stock "true" random number + // generator to get a "true random seed" + SecureRandom r = Utils.generateSecureRandom(); + r.nextInt(); // need to do something for SR to be triggered. + // Use this seed to generate a n-value for Blum-Blum-Shub + // This value can be re-used if desired. + BigInteger nval = CSPRNG_DO_NOT_USE.generateN(bitsize, r); + // now get a seed + byte[] seed = new byte[bitsize/8]; + r.nextBytes(seed); + // now create an instance of BlumBlumShub + CSPRNG_DO_NOT_USE bbs = new CSPRNG_DO_NOT_USE(nval, seed); + return bbs; + } + + + /** + * @return CSPRNG_DO_NOT_USE + * @Author Draknyte1/Alkalus + */ + public static CSPRNG_DO_NOT_USE generate(Random aRandom){ + return generate(512, aRandom); + } + + /** + * @return CSPRNG_DO_NOT_USE + * @Author Draknyte1/Alkalus + */ + public static CSPRNG_DO_NOT_USE generate(int aBitSize, Random aRandom){ + // First use the internal, stock "true" random number + // generator to get a "true random seed" + SecureRandom r = Utils.generateSecureRandom(); + r.nextInt(); // need to do something for SR to be triggered. + // Use this seed to generate a n-value for Blum-Blum-Shub + // This value can be re-used if desired. + int bitsize = aBitSize; + // now create an instance of BlumBlumShub + // do everything almost automatically + CSPRNG_DO_NOT_USE bbs = new CSPRNG_DO_NOT_USE(bitsize, aRandom); + return bbs; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/random/XSTR.java b/src/Java/gtPlusPlus/api/objects/random/XSTR.java new file mode 100644 index 0000000000..7f83df52c4 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/random/XSTR.java @@ -0,0 +1,266 @@ +package gtPlusPlus.api.objects.random; +/** + * A subclass of java.util.random that implements the Xorshift random number + * generator + * + * - it is 30% faster than the generator from Java's library - it produces + * random sequences of higher quality than java.util.Random - this class also + * provides a clone() function + * + * Usage: XSRandom rand = new XSRandom(); //Instantiation x = rand.nextInt(); + * //pull a random number + * + * To use the class in legacy code, you may also instantiate an XSRandom object + * and assign it to a java.util.Random object: java.util.Random rand = new + * XSRandom(); + * + * for an explanation of the algorithm, see + * http://demesos.blogspot.com/2011/09/pseudo-random-number-generators.html + * + * @author Wilfried Elmenreich University of Klagenfurt/Lakeside Labs + * http://www.elmenreich.tk + * + * This code is released under the GNU Lesser General Public License Version 3 + * http://www.gnu.org/licenses/lgpl-3.0.txt + */ + +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; + +/** + * XSTR - Xorshift ThermiteRandom + * Modified by Bogdan-G + * 03.06.2016 + * version 0.0.4 + */ +public class XSTR extends Random { + + private static final long serialVersionUID = 6208727693524452904L; + private long seed; + private long last; + private static final long GAMMA = 0x9e3779b97f4a7c15L; + private static final int PROBE_INCREMENT = 0x9e3779b9; + private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL; + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) + private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24) + + /* + MODIFIED BY: Robotia + Modification: Implemented Random class seed generator + */ + /** + * Creates a new pseudo random number generator. The seed is initialized to + * the current time, as if by + * setSeed(System.currentTimeMillis());. + */ + public XSTR() { + this(seedUniquifier() ^ System.nanoTime()); + } + private static final AtomicLong seedUniquifier + = new AtomicLong(8682522807148012L); + + private static long seedUniquifier() { + // L'Ecuyer, "Tables of Linear Congruential Generators of + // Different Sizes and Good Lattice Structure", 1999 + for (;;) { + final long current = seedUniquifier.get(); + final long next = current * 181783497276652981L; + if (seedUniquifier.compareAndSet(current, next)) { + return next; + } + } + } + + /** + * Creates a new pseudo random number generator, starting with the specified + * seed, using setSeed(seed);. + * + * @param seed the initial seed + */ + public XSTR(final long seed) { + this.seed = seed; + } + @Override + public boolean nextBoolean() { + return this.next(1) != 0; + } + + @Override + public double nextDouble() { + return (((long)(this.next(26)) << 27) + this.next(27)) * DOUBLE_UNIT; + } + /** + * Returns the current state of the seed, can be used to clone the object + * + * @return the current seed + */ + public synchronized long getSeed() { + return this.seed; + } + + /** + * Sets the seed for this pseudo random number generator. As described + * above, two instances of the same random class, starting with the same + * seed, produce the same results, if the same methods are called. + * + * @param seed the new seed + */ + @Override + public synchronized void setSeed(final long seed) { + this.seed = seed; + } + + /** + * @return Returns an XSRandom object with the same state as the original + */ + @Override + public XSTR clone() { + return new XSTR(this.getSeed()); + } + + /** + * Implementation of George Marsaglia's elegant Xorshift random generator + * 30% faster and better quality than the built-in java.util.random see also + * see http://www.javamex.com/tutorials/random_numbers/xorshift.shtml + * + * @param nbits + * @return + */ + @Override + public int next(final int nbits) { + long x = this.seed; + x ^= (x << 21); + x ^= (x >>> 35); + x ^= (x << 4); + this.seed = x; + x &= ((1L << nbits) - 1); + return (int) x; + } + boolean haveNextNextGaussian = false; + double nextNextGaussian = 0; + @Override + synchronized public double nextGaussian() { + // See Knuth, ACP, Section 3.4.1 Algorithm C. + if (this.haveNextNextGaussian) { + this.haveNextNextGaussian = false; + return this.nextNextGaussian; + } + double v1, v2, s; + do { + v1 = (2 * this.nextDouble()) - 1; // between -1 and 1 + v2 = (2 * this.nextDouble()) - 1; // between -1 and 1 + s = (v1 * v1) + (v2 * v2); + } while ((s >= 1) || (s == 0)); + final double multiplier = StrictMath.sqrt((-2 * StrictMath.log(s))/s); + this.nextNextGaussian = v2 * multiplier; + this.haveNextNextGaussian = true; + return v1 * multiplier; + } + /** + * Returns a pseudorandom, uniformly distributed {@code int} value between 0 + * (inclusive) and the specified value (exclusive), drawn from this random + * number generator's sequence. The general contract of {@code nextInt} is + * that one {@code int} value in the specified range is pseudorandomly + * generated and returned. All {@code bound} possible {@code int} values are + * produced with (approximately) equal probability. The method + * {@code nextInt(int bound)} is implemented by class {@code Random} as if + * by: + *
 {@code
+	 * public int nextInt(int bound) {
+	 *   if (bound <= 0)
+	 *     throw new IllegalArgumentException("bound must be positive");
+	 *
+	 *   if ((bound & -bound) == bound)  // i.e., bound is a power of 2
+	 *     return (int)((bound * (long)next(31)) >> 31);
+	 *
+	 *   int bits, val;
+	 *   do {
+	 *       bits = next(31);
+	 *       val = bits % bound;
+	 *   } while (bits - val + (bound-1) < 0);
+	 *   return val;
+	 * }}
+ * + *

The hedge "approx + * imately" is used in the foregoing description only because the next + * method is only approximately an unbiased source of independently chosen + * bits. If it were a perfect source of randomly chosen bits, then the + * algorithm shown would choose {@code int} values from the stated range + * with perfect uniformity. + *

+ * The algorithm is slightly tricky. It rejects values that would result in + * an uneven distribution (due to the fact that 2^31 is not divisible by n). + * The probability of a value being rejected depends on n. The worst case is + * n=2^30+1, for which the probability of a reject is 1/2, and the expected + * number of iterations before the loop terminates is 2. + *

+ * The algorithm treats the case where n is a power of two specially: it + * returns the correct number of high-order bits from the underlying + * pseudo-random number generator. In the absence of special treatment, the + * correct number of low-order bits would be returned. Linear + * congruential pseudo-random number generators such as the one implemented + * by this class are known to have short periods in the sequence of values + * of their low-order bits. Thus, this special case greatly increases the + * length of the sequence of values returned by successive calls to this + * method if n is a small power of two. + * + * @param bound the upper bound (exclusive). Must be positive. + * @return the next pseudorandom, uniformly distributed {@code int} value + * between zero (inclusive) and {@code bound} (exclusive) from this random + * number generator's sequence + * @throws IllegalArgumentException if bound is not positive + * @since 1.2 + */ + @Override + public int nextInt(final int bound) { + //if (bound <= 0) { + //throw new RuntimeException("BadBound"); + //} + + /*int r = next(31); + int m = bound - 1; + if ((bound & m) == 0) // i.e., bound is a power of 2 + { + r = (int) ((bound * (long) r) >> 31); + } else { + for (int u = r; + u - (r = u % bound) + m < 0; + u = next(31)) + ; + } + return r;*/ + //speedup, new nextInt ~+40% + this.last = this.seed ^ (this.seed << 21); + this.last ^= (this.last >>> 35); + this.last ^= (this.last << 4); + this.seed = this.last; + final int out = (int) this.last % bound; + return (out < 0) ? -out : out; + } + @Override + public int nextInt() { + return this.next(32); + } + + @Override + public float nextFloat() { + return this.next(24) * FLOAT_UNIT; + } + + @Override + public long nextLong() { + // it's okay that the bottom word remains signed. + return ((long)(this.next(32)) << 32) + this.next(32); + } + + @Override + public void nextBytes(final byte[] bytes_arr) { + for (int iba = 0, lenba = bytes_arr.length; iba < lenba; ) { + for (int rndba = this.nextInt(), + nba = Math.min(lenba - iba, Integer.SIZE/Byte.SIZE); + nba-- > 0; rndba >>= Byte.SIZE) { + bytes_arr[iba++] = (byte)rndba; + } + } + } +} \ No newline at end of file -- cgit