diff options
author | Jordan Byrne <draknyte1@hotmail.com> | 2018-02-21 14:38:10 +1000 |
---|---|---|
committer | Jordan Byrne <draknyte1@hotmail.com> | 2018-02-21 14:38:10 +1000 |
commit | 5d15dce9293f7c37089be3adfe0768de425838e2 (patch) | |
tree | 85e8146541b0ca71133c0b78fc36f657b5133f19 /src/Java/gtPlusPlus/core/handler/analytics | |
parent | ed93e5e83a08a2312452366f646cb3dd86fa039e (diff) | |
download | GT5-Unofficial-5d15dce9293f7c37089be3adfe0768de425838e2.tar.gz GT5-Unofficial-5d15dce9293f7c37089be3adfe0768de425838e2.tar.bz2 GT5-Unofficial-5d15dce9293f7c37089be3adfe0768de425838e2.zip |
$ Tree Farmer Work.
% Package cleanup.
- Removed /Bed command.
Diffstat (limited to 'src/Java/gtPlusPlus/core/handler/analytics')
4 files changed, 458 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/core/handler/analytics/AnalyticsLoggingPlugin.java b/src/Java/gtPlusPlus/core/handler/analytics/AnalyticsLoggingPlugin.java new file mode 100644 index 0000000000..808c62d7aa --- /dev/null +++ b/src/Java/gtPlusPlus/core/handler/analytics/AnalyticsLoggingPlugin.java @@ -0,0 +1,39 @@ +package gtPlusPlus.core.handler.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/core/handler/analytics/BlockingFlush.java b/src/Java/gtPlusPlus/core/handler/analytics/BlockingFlush.java new file mode 100644 index 0000000000..09d1cd5104 --- /dev/null +++ b/src/Java/gtPlusPlus/core/handler/analytics/BlockingFlush.java @@ -0,0 +1,67 @@ +package gtPlusPlus.core.handler.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. + * + * <pre><code> + * 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. + * </code></pre> + */ +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/core/handler/analytics/SegmentAnalytics.java b/src/Java/gtPlusPlus/core/handler/analytics/SegmentAnalytics.java new file mode 100644 index 0000000000..a217f896cf --- /dev/null +++ b/src/Java/gtPlusPlus/core/handler/analytics/SegmentAnalytics.java @@ -0,0 +1,271 @@ +package gtPlusPlus.core.handler.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<Integer, SegmentAnalytics> sAnalyticsMasterList = new ConcurrentHashMap<Integer, SegmentAnalytics>(); + //ID count + private static int sAnalyticsMapID = 0; + + //Analytics Player Mapping + public static final Map<UUID, Integer> sAnalyticsToPlayermap = new ConcurrentHashMap<UUID, Integer>(); + + //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<String, Object> 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<String, Object> 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<String, Object> 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/core/handler/analytics/SegmentHelper.java b/src/Java/gtPlusPlus/core/handler/analytics/SegmentHelper.java new file mode 100644 index 0000000000..79b95eda24 --- /dev/null +++ b/src/Java/gtPlusPlus/core/handler/analytics/SegmentHelper.java @@ -0,0 +1,81 @@ +package gtPlusPlus.core.handler.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<String, Object> 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<String, Object> 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 |