diff options
22 files changed, 942 insertions, 578 deletions
| diff --git a/out/discord_game_sdk.h b/out/discord_game_sdk.h deleted file mode 100644 index 779be2e2..00000000 --- a/out/discord_game_sdk.h +++ /dev/null @@ -1,237 +0,0 @@ -struct IDiscordLobbyTransaction { -    enum EDiscordResult (*set_type)(struct IDiscordLobbyTransaction* lobby_transaction, enum EDiscordLobbyType type); -    enum EDiscordResult (*set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordUserId owner_id); -    enum EDiscordResult (*set_capacity)(struct IDiscordLobbyTransaction* lobby_transaction, uint32_t capacity); -    enum EDiscordResult (*set_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key, DiscordMetadataValue value); -    enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key); -    enum EDiscordResult (*set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, bool locked); -}; - -struct IDiscordLobbyMemberTransaction { -    enum EDiscordResult (*set_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key, DiscordMetadataValue value); -    enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key); -}; - -struct IDiscordLobbySearchQuery { -    enum EDiscordResult (*filter)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchComparison comparison, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); -    enum EDiscordResult (*sort)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); -    enum EDiscordResult (*limit)(struct IDiscordLobbySearchQuery* lobby_search_query, uint32_t limit); -    enum EDiscordResult (*distance)(struct IDiscordLobbySearchQuery* lobby_search_query, enum EDiscordLobbySearchDistance distance); -}; - -typedef void* IDiscordApplicationEvents; - -struct IDiscordApplicationManager { -    void (*validate_or_exit)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*get_current_locale)(struct IDiscordApplicationManager* manager, DiscordLocale* locale); -    void (*get_current_branch)(struct IDiscordApplicationManager* manager, DiscordBranch* branch); -    void (*get_oauth2_token)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordOAuth2Token* oauth2_token)); -    void (*get_ticket)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, const char* data)); -}; - -struct IDiscordUserEvents { -    void (*on_current_user_update)(void* event_data); -}; - -struct IDiscordUserManager { -    enum EDiscordResult (*get_current_user)(struct IDiscordUserManager* manager, struct DiscordUser* current_user); -    void (*get_user)(struct IDiscordUserManager* manager, DiscordUserId user_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordUser* user)); -    enum EDiscordResult (*get_current_user_premium_type)(struct IDiscordUserManager* manager, enum EDiscordPremiumType* premium_type); -    enum EDiscordResult (*current_user_has_flag)(struct IDiscordUserManager* manager, enum EDiscordUserFlag flag, bool* has_flag); -}; - -typedef void* IDiscordImageEvents; - -struct IDiscordImageManager { -    void (*fetch)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, bool refresh, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordImageHandle handle_result)); -    enum EDiscordResult (*get_dimensions)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, struct DiscordImageDimensions* dimensions); -    enum EDiscordResult (*get_data)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, uint8_t* data, uint32_t data_length); -}; - -struct IDiscordActivityEvents { -    void (*on_activity_join)(void* event_data, const char* secret); -    void (*on_activity_spectate)(void* event_data, const char* secret); -    void (*on_activity_join_request)(void* event_data, struct DiscordUser* user); -    void (*on_activity_invite)(void* event_data, enum EDiscordActivityActionType type, struct DiscordUser* user, struct DiscordActivity* activity); -}; - -struct IDiscordActivityManager { -    enum EDiscordResult (*register_command)(struct IDiscordActivityManager* manager, const char* command); -    enum EDiscordResult (*register_steam)(struct IDiscordActivityManager* manager, uint32_t steam_id); -    void (*update_activity)(struct IDiscordActivityManager* manager, struct DiscordActivity* activity, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*clear_activity)(struct IDiscordActivityManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*send_request_reply)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityJoinRequestReply reply, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*send_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityActionType type, const char* content, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*accept_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -}; - -struct IDiscordRelationshipEvents { -    void (*on_refresh)(void* event_data); -    void (*on_relationship_update)(void* event_data, struct DiscordRelationship* relationship); -}; - -struct IDiscordRelationshipManager { -    void (*filter)(struct IDiscordRelationshipManager* manager, void* filter_data, bool (*filter)(void* filter_data, struct DiscordRelationship* relationship)); -    enum EDiscordResult (*count)(struct IDiscordRelationshipManager* manager, int32_t* count); -    enum EDiscordResult (*get)(struct IDiscordRelationshipManager* manager, DiscordUserId user_id, struct DiscordRelationship* relationship); -    enum EDiscordResult (*get_at)(struct IDiscordRelationshipManager* manager, uint32_t index, struct DiscordRelationship* relationship); -}; - -struct IDiscordLobbyEvents { -    void (*on_lobby_update)(void* event_data, int64_t lobby_id); -    void (*on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); -    void (*on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); -    void (*on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); -    void (*on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); -    void (*on_lobby_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t* data, uint32_t data_length); -    void (*on_speaking)(void* event_data, int64_t lobby_id, int64_t user_id, bool speaking); -    void (*on_network_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); -}; - -struct IDiscordLobbyManager { -    enum EDiscordResult (*get_lobby_create_transaction)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction** transaction); -    enum EDiscordResult (*get_lobby_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction** transaction); -    enum EDiscordResult (*get_member_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction** transaction); -    void (*create_lobby)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); -    void (*update_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*delete_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*connect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret secret, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); -    void (*connect_lobby_with_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbySecret activity_secret, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); -    void (*disconnect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    enum EDiscordResult (*get_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct DiscordLobby* lobby); -    enum EDiscordResult (*get_lobby_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret* secret); -    enum EDiscordResult (*get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordMetadataKey key, DiscordMetadataValue* value); -    enum EDiscordResult (*get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordMetadataKey* key); -    enum EDiscordResult (*lobby_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); -    enum EDiscordResult (*member_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); -    enum EDiscordResult (*get_member_user_id)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordUserId* user_id); -    enum EDiscordResult (*get_member_user)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct DiscordUser* user); -    enum EDiscordResult (*get_member_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, DiscordMetadataKey key, DiscordMetadataValue* value); -    enum EDiscordResult (*get_member_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t index, DiscordMetadataKey* key); -    enum EDiscordResult (*member_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t* count); -    void (*update_member)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*send_lobby_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t* data, uint32_t data_length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    enum EDiscordResult (*get_search_query)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery** query); -    void (*search)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery* query, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); -    enum EDiscordResult (*get_lobby_id)(struct IDiscordLobbyManager* manager, int32_t index, DiscordLobbyId* lobby_id); -    void (*connect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*disconnect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    enum EDiscordResult (*connect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); -    enum EDiscordResult (*disconnect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); -    enum EDiscordResult (*flush_network)(struct IDiscordLobbyManager* manager); -    enum EDiscordResult (*open_network_channel)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t channel_id, bool reliable); -    enum EDiscordResult (*send_network_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); -}; - -struct IDiscordNetworkEvents { -    void (*on_message)(void* event_data, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); -    void (*on_route_update)(void* event_data, const char* route_data); -}; - -struct IDiscordNetworkManager { -    void (*get_peer_id)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId* peer_id); -    enum EDiscordResult (*flush)(struct IDiscordNetworkManager* manager); -    enum EDiscordResult (*open_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); -    enum EDiscordResult (*update_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); -    enum EDiscordResult (*close_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id); -    enum EDiscordResult (*open_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, bool reliable); -    enum EDiscordResult (*close_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id); -    enum EDiscordResult (*send_message)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); -}; - -struct IDiscordOverlayEvents { -    void (*on_toggle)(void* event_data, bool locked); -}; - -struct IDiscordOverlayManager { -    void (*is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); -    void (*is_locked)(struct IDiscordOverlayManager* manager, bool* locked); -    void (*set_locked)(struct IDiscordOverlayManager* manager, bool locked, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*open_activity_invite)(struct IDiscordOverlayManager* manager, enum EDiscordActivityActionType type, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*open_guild_invite)(struct IDiscordOverlayManager* manager, const char* code, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*open_voice_settings)(struct IDiscordOverlayManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -}; - -typedef void* IDiscordStorageEvents; - -struct IDiscordStorageManager { -    enum EDiscordResult (*read)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, uint32_t* read); -    void (*read_async)(struct IDiscordStorageManager* manager, const char* name, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); -    void (*read_async_partial)(struct IDiscordStorageManager* manager, const char* name, uint64_t offset, uint64_t length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); -    enum EDiscordResult (*write)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length); -    void (*write_async)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    enum EDiscordResult (*delete_)(struct IDiscordStorageManager* manager, const char* name); -    enum EDiscordResult (*exists)(struct IDiscordStorageManager* manager, const char* name, bool* exists); -    void (*count)(struct IDiscordStorageManager* manager, int32_t* count); -    enum EDiscordResult (*stat)(struct IDiscordStorageManager* manager, const char* name, struct DiscordFileStat* stat); -    enum EDiscordResult (*stat_at)(struct IDiscordStorageManager* manager, int32_t index, struct DiscordFileStat* stat); -    enum EDiscordResult (*get_path)(struct IDiscordStorageManager* manager, DiscordPath* path); -}; - -struct IDiscordStoreEvents { -    void (*on_entitlement_create)(void* event_data, struct DiscordEntitlement* entitlement); -    void (*on_entitlement_delete)(void* event_data, struct DiscordEntitlement* entitlement); -}; - -struct IDiscordStoreManager { -    void (*fetch_skus)(struct IDiscordStoreManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*count_skus)(struct IDiscordStoreManager* manager, int32_t* count); -    enum EDiscordResult (*get_sku)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, struct DiscordSku* sku); -    enum EDiscordResult (*get_sku_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordSku* sku); -    void (*fetch_entitlements)(struct IDiscordStoreManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); -    enum EDiscordResult (*get_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake entitlement_id, struct DiscordEntitlement* entitlement); -    enum EDiscordResult (*get_entitlement_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordEntitlement* entitlement); -    enum EDiscordResult (*has_sku_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, bool* has_entitlement); -    void (*start_purchase)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -}; - -struct IDiscordVoiceEvents { -    void (*on_settings_update)(void* event_data); -}; - -struct IDiscordVoiceManager { -    enum EDiscordResult (*get_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode* input_mode); -    void (*set_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode input_mode, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    enum EDiscordResult (*is_self_mute)(struct IDiscordVoiceManager* manager, bool* mute); -    enum EDiscordResult (*set_self_mute)(struct IDiscordVoiceManager* manager, bool mute); -    enum EDiscordResult (*is_self_deaf)(struct IDiscordVoiceManager* manager, bool* deaf); -    enum EDiscordResult (*set_self_deaf)(struct IDiscordVoiceManager* manager, bool deaf); -    enum EDiscordResult (*is_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool* mute); -    enum EDiscordResult (*set_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool mute); -    enum EDiscordResult (*get_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t* volume); -    enum EDiscordResult (*set_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t volume); -}; - -struct IDiscordAchievementEvents { -    void (*on_user_achievement_update)(void* event_data, struct DiscordUserAchievement* user_achievement); -}; - -struct IDiscordAchievementManager { -    void (*set_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake achievement_id, uint8_t percent_complete, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*fetch_user_achievements)(struct IDiscordAchievementManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); -    void (*count_user_achievements)(struct IDiscordAchievementManager* manager, int32_t* count); -    enum EDiscordResult (*get_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake user_achievement_id, struct DiscordUserAchievement* user_achievement); -    enum EDiscordResult (*get_user_achievement_at)(struct IDiscordAchievementManager* manager, int32_t index, struct DiscordUserAchievement* user_achievement); -}; - -typedef void* IDiscordCoreEvents; - -struct IDiscordCore { -    void (*destroy)(struct IDiscordCore* core); -    enum EDiscordResult (*run_callbacks)(struct IDiscordCore* core); -    void (*set_log_hook)(struct IDiscordCore* core, enum EDiscordLogLevel min_level, void* hook_data, void (*hook)(void* hook_data, enum EDiscordLogLevel level, const char* message)); -    struct IDiscordApplicationManager* (*get_application_manager)(struct IDiscordCore* core); -    struct IDiscordUserManager* (*get_user_manager)(struct IDiscordCore* core); -    struct IDiscordImageManager* (*get_image_manager)(struct IDiscordCore* core); -    struct IDiscordActivityManager* (*get_activity_manager)(struct IDiscordCore* core); -    struct IDiscordRelationshipManager* (*get_relationship_manager)(struct IDiscordCore* core); -    struct IDiscordLobbyManager* (*get_lobby_manager)(struct IDiscordCore* core); -    struct IDiscordNetworkManager* (*get_network_manager)(struct IDiscordCore* core); -    struct IDiscordOverlayManager* (*get_overlay_manager)(struct IDiscordCore* core); -    struct IDiscordStorageManager* (*get_storage_manager)(struct IDiscordCore* core); -    struct IDiscordStoreManager* (*get_store_manager)(struct IDiscordCore* core); -    struct IDiscordVoiceManager* (*get_voice_manager)(struct IDiscordCore* core); -    struct IDiscordAchievementManager* (*get_achievement_manager)(struct IDiscordCore* core); -};
\ No newline at end of file diff --git a/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java index 48c392e0..c8c96940 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java @@ -28,14 +28,14 @@ import kr.syeyoung.dungeonsguide.eventlistener.FeatureListener;  import kr.syeyoung.dungeonsguide.eventlistener.PacketListener;  import kr.syeyoung.dungeonsguide.events.StompConnectedEvent;  import kr.syeyoung.dungeonsguide.features.FeatureRegistry; -import kr.syeyoung.dungeonsguide.party.PartyInviteViewer; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.PartyInviteViewer;  import kr.syeyoung.dungeonsguide.party.PartyManager;  import kr.syeyoung.dungeonsguide.resources.DGTexturePack; +import kr.syeyoung.dungeonsguide.rpc.RichPresenceManager;  import kr.syeyoung.dungeonsguide.stomp.CloseListener;  import kr.syeyoung.dungeonsguide.stomp.StompClient;  import kr.syeyoung.dungeonsguide.stomp.StompInterface;  import kr.syeyoung.dungeonsguide.utils.AhUtils; -import kr.syeyoung.dungeonsguide.utils.cursor.GLCursors;  import kr.syeyoung.dungeonsguide.wsresource.StaticResourceCache;  import lombok.Getter;  import net.minecraft.client.Minecraft; @@ -44,12 +44,10 @@ import net.minecraft.launchwrapper.LaunchClassLoader;  import net.minecraft.util.IChatComponent;  import net.minecraftforge.client.ClientCommandHandler;  import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.Configuration;  import net.minecraftforge.fml.common.ProgressManager;  import net.minecraftforge.fml.common.event.FMLInitializationEvent;  import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;  import net.minecraftforge.fml.relauncher.ReflectionHelper; -import org.apache.commons.io.IOUtils;  import javax.crypto.BadPaddingException;  import javax.crypto.IllegalBlockSizeException; @@ -124,11 +122,10 @@ public class DungeonsGuide implements DGInterface, CloseListener {          MinecraftForge.EVENT_BUS.register(new PacketListener());          MinecraftForge.EVENT_BUS.register(new Keybinds()); -        RichPresenceManager.INSTANCE.setup(); +        RichPresenceManager.INSTANCE.getLastSetupCode();          MinecraftForge.EVENT_BUS.register(RichPresenceManager.INSTANCE);          MinecraftForge.EVENT_BUS.register(PartyManager.INSTANCE);          MinecraftForge.EVENT_BUS.register(StaticResourceCache.INSTANCE); -        MinecraftForge.EVENT_BUS.register(PartyInviteViewer.INSTANCE);          AhUtils.registerTimer(); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java b/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java deleted file mode 100644 index 7f02d69a..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - *     Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - *     Copyright (C) 2021  cyoung06 - * - *     This program is free software: you can redistribute it and/or modify - *     it under the terms of the GNU Affero General Public License as published - *     by the Free Software Foundation, either version 3 of the License, or - *     (at your option) any later version. - * - *     This program is distributed in the hope that it will be useful, - *     but WITHOUT ANY WARRANTY; without even the implied warranty of - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *     GNU Affero General Public License for more details. - * - *     You should have received a copy of the GNU Affero General Public License - *     along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ - -package kr.syeyoung.dungeonsguide; - -import com.sun.jna.Pointer; -import com.sun.jna.ptr.PointerByReference; -import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; -import kr.syeyoung.dungeonsguide.events.SkyblockJoinedEvent; -import kr.syeyoung.dungeonsguide.events.SkyblockLeftEvent; -import kr.syeyoung.dungeonsguide.features.FeatureRegistry; -import kr.syeyoung.dungeonsguide.gamesdk.GameSDK; -import kr.syeyoung.dungeonsguide.gamesdk.jna.NativeGameSDK; -import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.*; -import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordActivityActionType; -import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordActivityJoinRequestReply; -import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordLogLevel; -import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordResult; -import kr.syeyoung.dungeonsguide.gamesdk.jna.interfacestruct.IDiscordActivityEvents; -import kr.syeyoung.dungeonsguide.gamesdk.jna.interfacestruct.IDiscordActivityManager; -import kr.syeyoung.dungeonsguide.gamesdk.jna.interfacestruct.IDiscordCore; -import kr.syeyoung.dungeonsguide.gamesdk.jna.typedef.*; -import kr.syeyoung.dungeonsguide.party.PartyInviteViewer; -import kr.syeyoung.dungeonsguide.party.PartyJoinRequest; -import kr.syeyoung.dungeonsguide.party.PartyManager; -import kr.syeyoung.dungeonsguide.stomp.StompHeader; -import kr.syeyoung.dungeonsguide.stomp.StompPayload; -import lombok.Getter; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import org.json.JSONObject; - -public class RichPresenceManager implements Runnable { -    public static RichPresenceManager INSTANCE = new RichPresenceManager(); -    private Thread t = new Thread(this); - -    public RichPresenceManager() { -        t.start(); -    } -    @Getter -    private NativeGameSDK nativeGameSDK; -    @Getter -    private IDiscordCore iDiscordCore; -    private IDiscordActivityManager activityManager; -    private IDiscordActivityEvents.ByReference callbacks; - -    @Getter -    private boolean setupSuccessful = false; -    public boolean setup() { -        nativeGameSDK = GameSDK.getNativeGameSDK(); -        if (nativeGameSDK == null) return false; -        DiscordCreateParams discordCreateParams = new DiscordCreateParams(); -        discordCreateParams.client_id = new DiscordClientID(816298079732498473L); - -        callbacks = new IDiscordActivityEvents.ByReference(); -        callbacks.OnActivityInvite = (eventData, type, user, activity) -> { -            PartyJoinRequest partyJoinRequest = new PartyJoinRequest(); -            partyJoinRequest.setDiscordUser(user); -            partyJoinRequest.setExpire(System.currentTimeMillis() + 30000); -            partyJoinRequest.setInvite(true); - -            PartyInviteViewer.INSTANCE.joinRequests.add(partyJoinRequest); -            System.out.println("Received Join Request from "+user.id.longValue()+" ("+partyJoinRequest.getUsername()+"#"+partyJoinRequest.getDiscriminator()+")"); -        }; -        callbacks.OnActivityJoin = (eventData, secret) -> {DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload().method(StompHeader.SEND) -                .header("destination", "/app/party.askedtojoin") -                .payload(new JSONObject().put("token", secret).toString())); -            System.out.println("Trying to join with token "+secret); -        }; -        callbacks.OnActivityJoinRequest = (eventData, user) -> { -                PartyJoinRequest partyJoinRequest = new PartyJoinRequest(); -                partyJoinRequest.setDiscordUser(user); -                partyJoinRequest.setExpire(System.currentTimeMillis() + 30000); - -                PartyInviteViewer.INSTANCE.joinRequests.add(partyJoinRequest); -                System.out.println("Received Join Request from "+user.id.longValue()+" ("+partyJoinRequest.getUsername()+"#"+partyJoinRequest.getDiscriminator()+")"); -        }; -        callbacks.OnActivitySpectate = (eventData, secret) -> { - -        }; -        callbacks.write(); -        discordCreateParams.activity_events = callbacks; - -        PointerByReference pointerByReference = new PointerByReference(); -        nativeGameSDK.DiscordCreate(new DiscordVersion(NativeGameSDK.DISCORD_VERSION), discordCreateParams, pointerByReference); -        if (pointerByReference.getValue() == Pointer.NULL) return false; -        iDiscordCore = new IDiscordCore(pointerByReference.getValue()); - -        iDiscordCore.SetLogHook.setLogHook(iDiscordCore, EDiscordLogLevel.DiscordLogLevel_Debug, Pointer.NULL, new IDiscordCore.LogHook() { -            @Override -            public void hook(Pointer hookData, EDiscordLogLevel level, String message) { -                System.out.println(message+" - "+level+" - "+hookData); -            } -        }); - -        activityManager = iDiscordCore.GetActivityManager.getActivityManager(iDiscordCore); -        latestDiscordActivity = new DiscordActivity(); -        latestDiscordActivity.assets = new DiscordActivityAssets(); -        latestDiscordActivity.secrets = new DiscordActivitySecrets(); -        latestDiscordActivity.party = new DiscordActivityParty(); -        latestDiscordActivity.party.discordActivityParty = new DiscordPartySize(); -        latestDiscordActivity.timestamps = new DiscordActivityTimestamps(); -        GameSDK.writeString(latestDiscordActivity.assets.large_image, "mort"); -        GameSDK.writeString(latestDiscordActivity.assets.large_text, "mort"); - -        return true; -    } - -    private final SkyblockStatus skyblockStatus = DungeonsGuide.getDungeonsGuide().getSkyblockStatus(); - -    private DiscordActivity latestDiscordActivity; - -    public void respond(DiscordSnowflake userID, EDiscordActivityJoinRequestReply reply) { -        activityManager.SendRequestReply.sendRequestReply(activityManager, userID, reply, Pointer.NULL, (callbackData, result) -> { -            System.out.println("Discord Returned "+result+" For Replying "+reply+" To "+userID.longValue()+"L"); -        }); -    } - -    public void accept(DiscordSnowflake userID) { -        activityManager.AcceptInvite.acceptInvite(activityManager, userID, Pointer.NULL, (callbackData, result) -> { -            System.out.println("Discord Returned "+result+" For Accepting invite from "+userID.longValue()+"L"); -        }); -    } -    public void updatePresence() { -        if (!skyblockStatus.isOnHypixel() || !FeatureRegistry.ADVANCED_RICHPRESENCE.isEnabled() || (!skyblockStatus.isOnSkyblock() && FeatureRegistry.ADVANCED_RICHPRESENCE.<Boolean>getParameter("disablenotskyblock").getValue())) { -            activityManager.ClearActivity.clearActivity(activityManager, Pointer.NULL, new NativeGameSDK.DiscordCallback() { -                @Override -                public void callback(Pointer callbackData, EDiscordResult result) { -                } -            }); -        } else { -            String name = skyblockStatus.getDungeonName(); -            if (name.trim().equals("Your Island")) name = "Private Island"; - -            GameSDK.writeString(latestDiscordActivity.state, name); - - -                GameSDK.writeString(latestDiscordActivity.party.id, PartyManager.INSTANCE.getPartyID() == null ? "" : PartyManager.INSTANCE.getPartyID()); -                latestDiscordActivity.party.discordActivityParty.current_size = new Int32(PartyManager.INSTANCE.getMemberCount()); -                latestDiscordActivity.party.discordActivityParty.max_size = new Int32(PartyManager.INSTANCE.getMaxParty()); - -            if (skyblockStatus.getContext() != null) { -                DungeonContext dungeonContext = skyblockStatus.getContext(); -                long init = dungeonContext.getInit(); -                latestDiscordActivity.timestamps.start = new DiscordTimestamp(init); - -                if (dungeonContext.getBossfightProcessor() != null) { -                    GameSDK.writeString(latestDiscordActivity.details, "Fighting "+dungeonContext.getBossfightProcessor().getBossName()+": "+dungeonContext.getBossfightProcessor().getCurrentPhase()); -                } else { -                    GameSDK.writeString(latestDiscordActivity.details, "Clearing Rooms"); -                } -            } else { -                latestDiscordActivity.timestamps.start = new DiscordTimestamp(0); -                GameSDK.writeString(latestDiscordActivity.details, "Dungeons Guide"); -            } -            if (PartyManager.INSTANCE.isAllowAskToJoin()) { -                GameSDK.writeString(latestDiscordActivity.secrets.join, PartyManager.INSTANCE.getAskToJoinSecret()); -            } else { -                GameSDK.writeString(latestDiscordActivity.secrets.join, ""); -            } -            activityManager.UpdateActivity.updateActivity(activityManager, latestDiscordActivity, Pointer.NULL, new NativeGameSDK.DiscordCallback() { -                @Override -                public void callback(Pointer callbackData, EDiscordResult result) { -                } -            }); -        } -    } - -    @Override -    public void run() { -        setupSuccessful = setup(); -        if (!setupSuccessful) return; -        while(!Thread.interrupted()) { -            try { -                iDiscordCore.RunCallbacks.runCallbacks(iDiscordCore); -                updatePresence(); -                Thread.sleep(300L); -            } catch (Exception e) {e.printStackTrace();} -        } -    } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java index d2960b2a..d7759f92 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java @@ -20,6 +20,8 @@ package kr.syeyoung.dungeonsguide.commands;  import com.google.gson.JsonObject;  import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.rpc.JDiscordRelation; +import kr.syeyoung.dungeonsguide.rpc.RichPresenceManager;  import kr.syeyoung.dungeonsguide.SkyblockStatus;  import kr.syeyoung.dungeonsguide.config.guiconfig.GuiConfigV2;  import kr.syeyoung.dungeonsguide.config.guiconfig.NestedCategory; @@ -39,7 +41,7 @@ import kr.syeyoung.dungeonsguide.features.AbstractFeature;  import kr.syeyoung.dungeonsguide.features.FeatureRegistry;  import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerOnJoin;  import kr.syeyoung.dungeonsguide.features.impl.party.api.ApiFetchur; -import kr.syeyoung.dungeonsguide.party.PartyInviteViewer; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.PartyInviteViewer;  import kr.syeyoung.dungeonsguide.party.PartyManager;  import kr.syeyoung.dungeonsguide.roomedit.EditingContext;  import kr.syeyoung.dungeonsguide.roomedit.gui.GuiDungeonRoomEdit; @@ -327,8 +329,11 @@ public class CommandDungeonsGuide extends CommandBase {                  sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fToggled Ask to join to " + (PartyManager.INSTANCE.isAllowAskToJoin() ? "§eon" : "§coff")));              } -            if (!FeatureRegistry.ADVANCED_RICHPRESENCE.isEnabled()) { -                sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cDiscord Rich Presence is disabled! Enable at /dg -> Advanced ")); +            if (!FeatureRegistry.DISCORD_RICHPRESENCE.isEnabled()) { +                sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cDiscord Rich Presence is disabled! Enable at /dg -> Discord ")); +            } +            if (!FeatureRegistry.DISCORD_ASKTOJOIN.isEnabled()) { +                sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cDiscord Invite Viewer is disabled! Enable at /dg -> Discord ")); // how              }          } else if (args[0].equalsIgnoreCase("partymax") || args[0].equalsIgnoreCase("pm")) {              if (args.length == 1) { @@ -396,8 +401,8 @@ public class CommandDungeonsGuide extends CommandBase {              cosmeticsManager.requestCosmeticsList();              cosmeticsManager.requestActiveCosmetics();              StaticResourceCache.INSTANCE.purgeCache(); -            PartyInviteViewer.INSTANCE.imageMap.clear(); -            PartyInviteViewer.INSTANCE.futureMap.clear(); +            FeatureRegistry.DISCORD_ASKTOJOIN.imageMap.clear(); +            FeatureRegistry.DISCORD_ASKTOJOIN.futureMap.clear();              sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fSuccessfully purged API Cache!"));          } else if (args[0].equals("pbroadcast")) { @@ -533,7 +538,11 @@ public class CommandDungeonsGuide extends CommandBase {              }              System.out.println(stringBuilder.toString());              System.out.println(stringBuilder2.toString()); -        } else { +        }  else if (args[0].equals("IDKTEST")) { +            for (Map.Entry<Long, JDiscordRelation> longJDiscordRelationEntry : RichPresenceManager.INSTANCE.getRelationMap().entrySet()) { +                System.out.println(longJDiscordRelationEntry.getValue()); +            } +        } else{              sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e/dg §7-§fOpens configuration gui"));              sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e/dg gui §7-§fOpens configuration gui"));              sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e/dg help §7-§fShows command help")); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java index ab7eae21..20aeb460 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java @@ -92,6 +92,30 @@ public class FeatureListener {          }      }      @SubscribeEvent +    public void onDiscordUserUpdate(DiscordUserUpdateEvent discordUserUpdateEvent) { +        try { +            for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) { +                if (abstractFeature instanceof DiscordUserUpdateListener) { +                    ((DiscordUserUpdateListener) abstractFeature).onDiscordUserUpdate(discordUserUpdateEvent); +                } +            } +        } catch (Throwable t) { +            t.printStackTrace(); +        } +    } +    @SubscribeEvent +    public void onDiscordUserUpdate(DiscordUserJoinRequestEvent discordUserUpdateEvent) { +        try { +            for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) { +                if (abstractFeature instanceof DiscordUserJoinRequestListener) { +                    ((DiscordUserJoinRequestListener) abstractFeature).onDiscordUserJoinRequest(discordUserUpdateEvent); +                } +            } +        } catch (Throwable t) { +            t.printStackTrace(); +        } +    } +    @SubscribeEvent      public void onWindowUpdate(WindowUpdateEvent windowUpdateEvent) {          try {              SkyblockStatus skyblockStatus = DungeonsGuide.getDungeonsGuide().getSkyblockStatus(); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserJoinRequestEvent.java b/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserJoinRequestEvent.java new file mode 100644 index 00000000..80a9315a --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserJoinRequestEvent.java @@ -0,0 +1,30 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.events; + +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordUser; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraftforge.fml.common.eventhandler.Event; + +@Data @AllArgsConstructor +public class DiscordUserJoinRequestEvent extends Event { +    private DiscordUser discordUser; +    private boolean isInvite; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserUpdateEvent.java b/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserUpdateEvent.java new file mode 100644 index 00000000..f737b598 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/events/DiscordUserUpdateEvent.java @@ -0,0 +1,30 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.events; + +import kr.syeyoung.dungeonsguide.rpc.JDiscordRelation; +import kr.syeyoung.dungeonsguide.rpc.JDiscordUser; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraftforge.fml.common.eventhandler.Event; + +@Data @AllArgsConstructor +public class DiscordUserUpdateEvent extends Event { +    private JDiscordRelation prev, current; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java index ee81ee2f..55e2753b 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java @@ -28,6 +28,8 @@ import kr.syeyoung.dungeonsguide.features.impl.boss.terminal.FeatureSimonSaysSol  import kr.syeyoung.dungeonsguide.features.impl.boss.terminal.FeatureTerminalSolvers;  import kr.syeyoung.dungeonsguide.features.impl.cosmetics.FeatureNicknameColor;  import kr.syeyoung.dungeonsguide.features.impl.cosmetics.FeatureNicknamePrefix; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.PartyInviteViewer; +import kr.syeyoung.dungeonsguide.features.impl.discord.onlinealarm.PlayingDGAlarm;  import kr.syeyoung.dungeonsguide.features.impl.dungeon.*;  import kr.syeyoung.dungeonsguide.features.impl.etc.*;  import kr.syeyoung.dungeonsguide.features.impl.etc.ability.FeatureAbilityCooldown; @@ -76,11 +78,15 @@ public class FeatureRegistry {      public static final FeatureRoomDebugInfo ADVANCED_DEBUG_ROOM = register(new FeatureRoomDebugInfo());      public static final FeatureDebuggableMap ADVANCED_DEBUGGABLE_MAP = register(new FeatureDebuggableMap());      public static final FeatureRoomCoordDisplay ADVANCED_COORDS = register(new FeatureRoomCoordDisplay()); -    public static final SimpleFeature ADVANCED_RICHPRESENCE = register(new SimpleFeature("Misc", "Discord RPC", "Discord rich presence with ASK-TO-JOIN Support!\n\nSimply type /dg asktojoin or /dg atj to toggle whether ask-to-join would be presented as option on discord!", "advanced.richpresence", true) { + +    public static final SimpleFeature DISCORD_RICHPRESENCE = register(new SimpleFeature("Discord", "Discord RPC", "Enable Discord rich presence", "advanced.richpresence", true) {          {              parameters.put("disablenotskyblock", new FeatureParameter<Boolean>("disablenotskyblock", "Disable When not on Skyblock", "Disable When not on skyblock", false, "boolean"));          }      }); +    public static final PartyInviteViewer DISCORD_ASKTOJOIN = register(new PartyInviteViewer()); +    public static final PlayingDGAlarm DISCORD_ONLINEALARM = register(new PlayingDGAlarm()); +      public static final SimpleFeature SOLVER_RIDDLE = register(new SimpleFeature("Solver.Any Floor", "Riddle", "Highlights the correct box after clicking on all 3 weirdos",  "solver.riddle"));      public static final SimpleFeature SOLVER_KAHOOT = register(new SimpleFeature("Solver.Floor 4+", "Quiz", "Highlights the correct solution for trivia puzzle",  "solver.trivia")); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java new file mode 100644 index 00000000..62ee2913 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java @@ -0,0 +1,120 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer; + + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.ResourceLocation; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +@Data +public class ImageTexture { +    private String url; +    private BufferedImage image; +    private DynamicTexture previewTexture; +    private ResourceLocation resourceLocation; + +    private int width; +    private int height; +    private int frames; +    private int size; + +    @Getter @Setter +    private int lastFrame = 0; + +    public void buildGLThings() { +        previewTexture = new DynamicTexture(image); +        resourceLocation = Minecraft.getMinecraft().getTextureManager().getDynamicTextureLocation("dgurl/"+url, previewTexture); +    } + +    public ImageTexture(String url) throws IOException { +        this.url = url; + +        URL urlObj = new URL(url); +        HttpURLConnection huc = (HttpURLConnection) urlObj.openConnection(); +        huc.addRequestProperty("User-Agent", "DungeonsGuideMod (dungeons.guide, 1.0)"); +        ImageInputStream imageInputStream = ImageIO.createImageInputStream(huc.getInputStream()); +        Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream); +        if(!readers.hasNext()) throw new IOException("No image reader what" + url); +        ImageReader reader = readers.next(); +        reader.setInput(imageInputStream); +        frames = reader.getNumImages(true); +        BufferedImage dummyFrame = reader.read(0); +        width = dummyFrame.getWidth(); height = dummyFrame.getHeight(); + + +        image = new BufferedImage(width, height * frames, dummyFrame.getType()); +        Graphics2D graphics2D = image.createGraphics(); + +        for (int i = 0; i < frames; i++) { +            BufferedImage bufferedImage = reader.read(i); +            graphics2D.drawImage(bufferedImage, 0, i*height, null); +        } +        reader.dispose(); imageInputStream.close(); huc.disconnect(); +    } + +    public void drawFrame(int frame, int x, int y, int width, int height) { +        if (getResourceLocation() == null) +            buildGLThings(); + +        TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); +        textureManager.bindTexture(getResourceLocation()); + +        GlStateManager.color(1, 1, 1, 1.0F); + +        Tessellator tessellator = Tessellator.getInstance(); +        WorldRenderer worldrenderer = tessellator.getWorldRenderer(); +        worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX); +        worldrenderer.pos((double)x, (double)(y + height), 0.0D) +                .tex(0,((frame+1) * height)/ ((double)frames * height)).endVertex(); +        worldrenderer.pos((double)(x + width), (double)(y + height), 0.0D) +                .tex(1, ((frame+1) * height)/ ((double)frames * height)).endVertex(); +        worldrenderer.pos((double)(x + width), (double)y, 0.0D) +                .tex(1,(frame * height)/ ((double)frames * height)).endVertex(); +        worldrenderer.pos((double)x, (double)y, 0.0D) +                .tex(0,  (frame * height) / ((double)frames * height)).endVertex(); +        tessellator.draw(); +    } + +    public void drawFrameAndIncrement(int x, int y, int width, int height) { +        drawFrame(lastFrame, x,y,width,height); +        lastFrame++; +        if (lastFrame >= frames) lastFrame = 0; +    } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyInviteViewer.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyInviteViewer.java index 8dbdf2bb..6676eae2 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyInviteViewer.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyInviteViewer.java @@ -1,25 +1,28 @@  /* - *     Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - *     Copyright (C) 2021  cyoung06 + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06   * - *     This program is free software: you can redistribute it and/or modify - *     it under the terms of the GNU Affero General Public License as published - *     by the Free Software Foundation, either version 3 of the License, or - *     (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version.   * - *     This program is distributed in the hope that it will be useful, - *     but WITHOUT ANY WARRANTY; without even the implied warranty of - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *     GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details.   * - *     You should have received a copy of the GNU Affero General Public License - *     along with this program.  If not, see <https://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ -package kr.syeyoung.dungeonsguide.party; +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer;  import kr.syeyoung.dungeonsguide.DungeonsGuide; -import kr.syeyoung.dungeonsguide.RichPresenceManager; +import kr.syeyoung.dungeonsguide.events.DiscordUserJoinRequestEvent; +import kr.syeyoung.dungeonsguide.features.SimpleFeature; +import kr.syeyoung.dungeonsguide.features.listener.*; +import kr.syeyoung.dungeonsguide.rpc.RichPresenceManager;  import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordActivityJoinRequestReply;  import kr.syeyoung.dungeonsguide.utils.TextUtils;  import net.minecraft.client.Minecraft; @@ -27,13 +30,8 @@ import net.minecraft.client.gui.FontRenderer;  import net.minecraft.client.gui.Gui;  import net.minecraft.client.gui.ScaledResolution;  import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper;  import net.minecraft.client.renderer.texture.TextureManager;  import net.minecraftforge.client.event.GuiScreenEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.fml.common.eventhandler.EventPriority; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent;  import org.lwjgl.input.Mouse;  import org.lwjgl.opengl.GL11;  import org.lwjgl.opengl.GL14; @@ -47,29 +45,32 @@ import java.util.*;  import java.util.List;  import java.util.concurrent.*; -public class PartyInviteViewer { -    public static final PartyInviteViewer INSTANCE = new PartyInviteViewer(); +public class PartyInviteViewer extends SimpleFeature implements GuiPostRenderListener, ScreenRenderListener, TickListener, GuiClickListener, DiscordUserJoinRequestListener { +    public PartyInviteViewer() { +        super("Discord", "Party Invite Viewer","Simply type /dg asktojoin or /dg atj to toggle whether ask-to-join would be presented as option on discord!\n\nRequires Discord RPC to be enabled", "discord.party_invite_viewer"); +    } -    @SubscribeEvent -    public void onRender(RenderGameOverlayEvent.Post postRender) { -        try { -            if (postRender.type == RenderGameOverlayEvent.ElementType.TEXT) { -                renderRequests(false); -            } -        } catch (Throwable t) { -            t.printStackTrace(); -        } +    @Override +    public boolean isDisyllable() { +        return false;      } -    @SubscribeEvent -    public void onRender(GuiScreenEvent.DrawScreenEvent.Post postRender) { +    @Override +    public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) {          renderRequests(true);      } -    @SubscribeEvent -    public void onTick(TickEvent.ClientTickEvent clientTickEvent) { +    @Override +    public void drawScreen(float partialTicks) { +        try { +            renderRequests(false); +        } catch (Throwable t) { +            t.printStackTrace(); +        } +    } +    @Override +    public void onTick() {          try { -            if (clientTickEvent.phase != TickEvent.Phase.START) return;              List<PartyJoinRequest> partyJoinRequestList = new ArrayList<>();              boolean isOnHypixel = DungeonsGuide.getDungeonsGuide().getSkyblockStatus().isOnHypixel();              for (PartyJoinRequest joinRequest:joinRequests) { @@ -90,14 +91,13 @@ public class PartyInviteViewer {      } - -    @SubscribeEvent(receiveCanceled = true, priority = EventPriority.HIGH) -    public void onRender(GuiScreenEvent.MouseInputEvent.Pre mouseInput) { +    @Override +    public void onMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) {          int mouseX = Mouse.getX();          int mouseY = Minecraft.getMinecraft().displayHeight - Mouse.getY() +3;          for (PartyJoinRequest joinRequest:joinRequests) {              if (joinRequest.getWholeRect() != null && joinRequest.getWholeRect().contains(mouseX, mouseY)) { -                mouseInput.setCanceled(true); +                mouseInputEvent.setCanceled(true);                  if (Mouse.getEventButton() == -1) return; @@ -148,29 +148,21 @@ public class PartyInviteViewer {      } +      public CopyOnWriteArrayList<PartyJoinRequest> joinRequests = new CopyOnWriteArrayList<>();      ExecutorService executorService = Executors.newFixedThreadPool(3); -    public Map<String, Future<LoadedImage>> futureMap = new HashMap<>(); -    public Map<String, LoadedImage> imageMap = new HashMap<>(); +    public Map<String, Future<ImageTexture>> futureMap = new HashMap<>(); +    public Map<String, ImageTexture> imageMap = new HashMap<>(); -    public Future<LoadedImage> loadImage(String url) { +    public Future<ImageTexture> loadImage(String url) {          if (imageMap.containsKey(url)) return CompletableFuture.completedFuture(imageMap.get(url));          if (futureMap.containsKey(url)) return futureMap.get(url); -        Future<LoadedImage> future =  executorService.submit(() -> { +        Future<ImageTexture> future =  executorService.submit(() -> {              try { -                URL urlObj = new URL(url); -                HttpURLConnection huc = (HttpURLConnection) urlObj.openConnection(); -                huc.addRequestProperty("User-Agent", "DungeonsGuideMod (dungeons.guide, 1.0)"); -                BufferedImage bufferedImage = ImageIO.read(huc.getInputStream()); -                BufferedImage newImage = new BufferedImage(128,128, BufferedImage.TYPE_INT_RGB); -                Graphics g = newImage.createGraphics(); -                g.drawImage(bufferedImage, 0, 0, 128, 128, null); -                g.dispose(); -                LoadedImage loadedImage = new LoadedImage(); -                loadedImage.setImage(newImage); -                imageMap.put(url, loadedImage); -                return loadedImage; +                ImageTexture imageTexture = new ImageTexture(url); +                imageMap.put(url, imageTexture); +                return imageTexture;              } catch (Exception e) {                  throw e;              } @@ -217,8 +209,8 @@ public class PartyInviteViewer {              Gui.drawRect(2, 2, width-2, height-2, 0XFF2c2f33);          {              String avatar = "https://cdn.discordapp.com/avatars/"+Long.toUnsignedString(partyJoinRequest.getDiscordUser().id.longValue())+"/"+partyJoinRequest.getAvatar()+"."+(partyJoinRequest.getAvatar().startsWith("a_") ? "gif":"png"); -            Future<LoadedImage> loadedImageFuture = loadImage(avatar); -            LoadedImage loadedImage = null; +            Future<ImageTexture> loadedImageFuture = loadImage(avatar); +            ImageTexture loadedImage = null;              if (loadedImageFuture.isDone()) {                  try {                      loadedImage = loadedImageFuture.get(); @@ -227,13 +219,7 @@ public class PartyInviteViewer {                  }              }              if (loadedImage != null) { -                if (loadedImage.getResourceLocation() == null) loadedImage.buildGLThings(); -                TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); -                textureManager.bindTexture(loadedImage.getResourceLocation()); - -                GlStateManager.color(1, 1, 1, 1.0F); - -                Gui.drawScaledCustomSizeModalRect(7, 7, 0, 0, loadedImage.getImage().getWidth(),loadedImage.getImage().getHeight(),height-14,height-14, loadedImage.getImage().getWidth(), loadedImage.getImage().getHeight()); +                loadedImage.drawFrameAndIncrement( 7,7,height-14,height-14);              } else {                  Gui.drawRect(7, 7, height - 7, height-7, 0xFF4E4E4E);              } @@ -320,4 +306,13 @@ public class PartyInviteViewer {              }          GlStateManager.popMatrix();      } + +    @Override +    public void onDiscordUserJoinRequest(DiscordUserJoinRequestEvent event) { +        PartyJoinRequest partyInvite = new PartyJoinRequest(); +        partyInvite.setDiscordUser(event.getDiscordUser()); +        partyInvite.setExpire(System.currentTimeMillis() + 30000L); +        partyInvite.setInvite(event.isInvite()); +        joinRequests.add(partyInvite); +    }  } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyJoinRequest.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyJoinRequest.java index a894ee4e..b95da68a 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyJoinRequest.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyJoinRequest.java @@ -1,22 +1,22 @@  /* - *     Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - *     Copyright (C) 2021  cyoung06 + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06   * - *     This program is free software: you can redistribute it and/or modify - *     it under the terms of the GNU Affero General Public License as published - *     by the Free Software Foundation, either version 3 of the License, or - *     (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version.   * - *     This program is distributed in the hope that it will be useful, - *     but WITHOUT ANY WARRANTY; without even the implied warranty of - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *     GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details.   * - *     You should have received a copy of the GNU Affero General Public License - *     along with this program.  If not, see <https://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ -package kr.syeyoung.dungeonsguide.party; +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer;  import kr.syeyoung.dungeonsguide.gamesdk.GameSDK;  import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordUser; diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java new file mode 100644 index 00000000..d003b165 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java @@ -0,0 +1,171 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.onlinealarm; + +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.features.SimpleFeature; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.ImageTexture; +import kr.syeyoung.dungeonsguide.features.listener.DiscordUserUpdateListener; +import kr.syeyoung.dungeonsguide.features.listener.ScreenRenderListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordRelationshipType; +import kr.syeyoung.dungeonsguide.rpc.JDiscordActivity; +import kr.syeyoung.dungeonsguide.rpc.JDiscordRelation; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.TextureManager; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class PlayingDGAlarm extends SimpleFeature implements DiscordUserUpdateListener, ScreenRenderListener, TickListener { +    public PlayingDGAlarm() { +        super("Discord", "Friend Online Notification","Notifies you in bottom when your discord friend has launched a Minecraft with DG!\n\nRequires the Friend's Discord RPC to be enabled", "discord.playingalarm"); +    } +    private List<PlayerOnline> notif = new CopyOnWriteArrayList<>(); + +    @Override +    public void onTick() { +        try { +            List<PlayerOnline> partyJoinRequestList = new ArrayList<>(); +            boolean isOnHypixel = DungeonsGuide.getDungeonsGuide().getSkyblockStatus().isOnHypixel(); +            for (PlayerOnline joinRequest:notif) { +                if (!isOnHypixel){ +                    partyJoinRequestList.add(joinRequest); +                } else if (joinRequest.getEnd() < System.currentTimeMillis()) { +                    partyJoinRequestList.add(joinRequest); +                } +            } +            notif.removeAll(partyJoinRequestList); +        } catch (Throwable e) {e.printStackTrace();} +    } + + + +    @Override +    public void drawScreen(float partialTicks) { +        try { +            GlStateManager.pushMatrix(); +            GlStateManager.translate(0,0,100); +            ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft()); +            GlStateManager.scale(1.0 / sr.getScaleFactor(), 1.0 / sr.getScaleFactor(), 1.0); +            int height = 90; +            int gap = 5; +            int x = Minecraft.getMinecraft().displayWidth-350-gap; +            int y = Minecraft.getMinecraft().displayHeight-(height+gap)*notif.size(); +            for (PlayerOnline partyJoinRequest : notif) { +                renderRequest(partyJoinRequest, x, y, 350,height); +                y += height + gap; +            } +            GlStateManager.popMatrix(); +            GlStateManager.enableBlend(); +        } catch (Throwable t) { +            t.printStackTrace(); +        } +    } + +    public void renderRequest(PlayerOnline online, int x, int y, int width, int height) { +        GlStateManager.pushMatrix(); +        online.setEnd(System.currentTimeMillis()+600000); +        GlStateManager.translate(x,y,0); + +        Gui.drawRect(0, 0,width,height, 0xFF23272a); +        Gui.drawRect(2, 2, width-2, height-2, 0XFF2c2f33); +        { +            String avatar = "https://cdn.discordapp.com/avatars/"+Long.toUnsignedString(online.getJDiscordRelation().getDiscordUser().getId())+"/"+online.getJDiscordRelation().getDiscordUser().getAvatar()+"."+(online.getJDiscordRelation().getDiscordUser().getAvatar().startsWith("a_") ? "gif":"png"); +            Future<ImageTexture> loadedImageFuture = FeatureRegistry.DISCORD_ASKTOJOIN.loadImage(avatar); +            ImageTexture loadedImage = null; +            if (loadedImageFuture.isDone()) { +                try { +                    loadedImage = loadedImageFuture.get(); +                } catch (InterruptedException | ExecutionException e) { +                    e.printStackTrace(); +                } +            } +            if (loadedImage != null) { +                loadedImage.drawFrameAndIncrement( 7,7,height-14,height-14); +            } else { +                Gui.drawRect(7, 7, height - 7, height-7, 0xFF4E4E4E); +            } +        } + +        GlStateManager.enableBlend(); +        GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); +        GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); +        FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; +        GlStateManager.pushMatrix(); +        GlStateManager.translate(height +3,7, 0); + +        GlStateManager.pushMatrix(); +        GlStateManager.scale(3.0,3.0,1.0); +        fr.drawString(online.getJDiscordRelation().getDiscordUser().getUsername()+"", 0,0, 0xFFFFFFFF, true); +        GlStateManager.popMatrix(); + +        GlStateManager.pushMatrix(); +        GlStateManager.translate(fr.getStringWidth(online.getJDiscordRelation().getDiscordUser().getUsername()+"") * 3 + 1, (int)(fr.FONT_HEIGHT*1.5), 0); +        fr.drawString("#"+online.getJDiscordRelation().getDiscordUser().getDiscriminator(), 0,0,0xFFaaaaaa, true); +        GlStateManager.popMatrix(); +        GlStateManager.pushMatrix(); +        GlStateManager.translate(0, fr.FONT_HEIGHT * 3 + 5, 0); +        GlStateManager.scale(1.0,1.0,1.0); +        fr.drawString("Started Playing Skyblock! (Dismissed in "+(TextUtils.formatTime(online.getEnd() - System.currentTimeMillis()))+")", 0,0,0xFFFFFFFF,false); +        GlStateManager.popMatrix(); +        GlStateManager.popMatrix(); +        GlStateManager.popMatrix(); +    } + + +    @Data @AllArgsConstructor +    public static class PlayerOnline { +        private JDiscordRelation jDiscordRelation; +        private long end; +    } + +    @Override +    public void onDiscordUserUpdate(DiscordUserUpdateEvent event) { +        JDiscordRelation prev = event.getPrev(), current = event.getCurrent(); +        if (!isDisplayable(prev) && isDisplayable(current)) { +            notif.add(new PlayerOnline(current, System.currentTimeMillis()+600000)); +        } +    } + +    public boolean isDisplayable(JDiscordRelation jDiscordRelation) { +        EDiscordRelationshipType relationshipType = jDiscordRelation.getDiscordRelationshipType(); +        if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_Blocked) return false; +        if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_None) return false; +        if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_PendingIncoming) return false; +        if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_PendingOutgoing) return false; + +        JDiscordActivity jDiscordActivity = jDiscordRelation.getDiscordActivity(); +        return jDiscordActivity.getApplicationId() == 816298079732498473L; +    } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java new file mode 100644 index 00000000..d48331d5 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java @@ -0,0 +1,26 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.listener; + +import kr.syeyoung.dungeonsguide.events.DiscordUserJoinRequestEvent; +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; + +public interface DiscordUserJoinRequestListener { +    void onDiscordUserJoinRequest(DiscordUserJoinRequestEvent event); +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java new file mode 100644 index 00000000..d376a21d --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java @@ -0,0 +1,25 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.listener; + +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; + +public interface DiscordUserUpdateListener { +    void onDiscordUserUpdate(DiscordUserUpdateEvent event); +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/datastruct/DiscordCreateParams.java b/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/datastruct/DiscordCreateParams.java index 8e230b73..10f1ba3d 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/datastruct/DiscordCreateParams.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/datastruct/DiscordCreateParams.java @@ -20,6 +20,7 @@ package kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct;  import com.sun.jna.Pointer;  import com.sun.jna.Structure; +import kr.syeyoung.dungeonsguide.gamesdk.jna.NativeGameSDK;  import kr.syeyoung.dungeonsguide.gamesdk.jna.interfacestruct.*;  import kr.syeyoung.dungeonsguide.gamesdk.jna.typedef.DiscordClientID;  import kr.syeyoung.dungeonsguide.gamesdk.jna.typedef.DiscordVersion; @@ -34,29 +35,29 @@ public class DiscordCreateParams extends DiscordStruct { public DiscordCreatePar      public Pointer events; // void*      public Pointer event_data; // void*      public Pointer application_events; -    public DiscordVersion application_version = new DiscordVersion(); +    public DiscordVersion application_version = new DiscordVersion(NativeGameSDK.DISCORD_APPLICATION_MANAGER_VERSION);      public IDiscordUserEvents.ByReference user_events; -    public DiscordVersion user_version= new DiscordVersion(); +    public DiscordVersion user_version= new DiscordVersion(NativeGameSDK.DISCORD_USER_MANAGER_VERSION);      public Pointer image_events;// void* -    public DiscordVersion image_version= new DiscordVersion(); +    public DiscordVersion image_version= new DiscordVersion(NativeGameSDK.DISCORD_IMAGE_MANAGER_VERSION);      public IDiscordActivityEvents.ByReference activity_events; -    public DiscordVersion activity_version= new DiscordVersion(); +    public DiscordVersion activity_version= new DiscordVersion(NativeGameSDK.DISCORD_ACTIVITY_MANAGER_VERSION);      public IDiscordRelationshipEvents.ByReference relationship_events; -    public DiscordVersion relationship_version= new DiscordVersion(); +    public DiscordVersion relationship_version= new DiscordVersion(NativeGameSDK.DISCORD_RELATIONSHIP_MANAGER_VERSION);      public IDiscordLobbyEvents.ByReference lobby_events; -    public DiscordVersion lobby_version= new DiscordVersion(); +    public DiscordVersion lobby_version= new DiscordVersion(NativeGameSDK.DISCORD_LOBBY_MANAGER_VERSION);      public IDiscordNetworkEvents.ByReference network_events; -    public DiscordVersion network_version= new DiscordVersion(); +    public DiscordVersion network_version= new DiscordVersion(NativeGameSDK.DISCORD_NETWORK_MANAGER_VERSION);      public IDiscordOverlayEvents.ByReference overlay_events; -    public DiscordVersion overlay_version= new DiscordVersion(); +    public DiscordVersion overlay_version= new DiscordVersion(NativeGameSDK.DISCORD_OVERLAY_MANAGER_VERSION);      public Pointer storage_events;// void* -    public DiscordVersion storage_version= new DiscordVersion(); +    public DiscordVersion storage_version= new DiscordVersion(NativeGameSDK.DISCORD_STORAGE_MANAGER_VERSION);      public IDiscordStoreEvents.ByReference store_events; -    public DiscordVersion store_version= new DiscordVersion(); +    public DiscordVersion store_version= new DiscordVersion(NativeGameSDK.DISCORD_STORE_MANAGER_VERSION);      public IDiscordVoiceEvents.ByReference voice_events; -    public DiscordVersion voice_version= new DiscordVersion(); +    public DiscordVersion voice_version= new DiscordVersion(NativeGameSDK.DISCORD_VOICE_MANAGER_VERSION);      public IDiscordAchievementEvents.ByReference achievement_events; -    public DiscordVersion achievement_version= new DiscordVersion(); +    public DiscordVersion achievement_version= new DiscordVersion(NativeGameSDK.DISCORD_ACHIEVEMENT_MANAGER_VERSION);      public static class ByReference extends DiscordCreateParams implements Structure.ByReference { public ByReference() {super();} public ByReference(Pointer pointer) {super(pointer);}}      public static class ByValue extends DiscordCreateParams implements Structure.ByValue { public ByValue() {super();} public ByValue(Pointer pointer) {super(pointer);}} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/interfacestruct/IDiscordRelationshipManager.java b/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/interfacestruct/IDiscordRelationshipManager.java index f2db8dd6..1b3ffe16 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/interfacestruct/IDiscordRelationshipManager.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/gamesdk/jna/interfacestruct/IDiscordRelationshipManager.java @@ -33,7 +33,7 @@ import java.util.List;  public class IDiscordRelationshipManager extends DiscordStruct { public IDiscordRelationshipManager() {super();} public IDiscordRelationshipManager(Pointer pointer) {super(pointer);}      public interface FilterCallback extends GameSDKCallback { void filter(IDiscordRelationshipManager manager, Pointer filterData, FilterCallback_Callback filter); } -    public interface FilterCallback_Callback extends GameSDKCallback { boolean filter(Pointer filterData, Structure relationShip);} +    public interface FilterCallback_Callback extends GameSDKCallback { boolean filter(Pointer filterData, DiscordRelationship relationShip);}      public FilterCallback Filter;      public interface CountCallback extends GameSDKCallback { EDiscordResult count(IDiscordRelationshipManager manager, IntByReference count); } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/party/LoadedImage.java b/src/main/java/kr/syeyoung/dungeonsguide/party/LoadedImage.java deleted file mode 100644 index ca3764d9..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/party/LoadedImage.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - *     Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - *     Copyright (C) 2021  cyoung06 - * - *     This program is free software: you can redistribute it and/or modify - *     it under the terms of the GNU Affero General Public License as published - *     by the Free Software Foundation, either version 3 of the License, or - *     (at your option) any later version. - * - *     This program is distributed in the hope that it will be useful, - *     but WITHOUT ANY WARRANTY; without even the implied warranty of - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *     GNU Affero General Public License for more details. - * - *     You should have received a copy of the GNU Affero General Public License - *     along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ - -package kr.syeyoung.dungeonsguide.party; - - -import lombok.Data; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.util.ResourceLocation; - -import java.awt.image.BufferedImage; - -@Data -public class LoadedImage { -    private String url; -    private BufferedImage image; -    private DynamicTexture previewTexture; -    private ResourceLocation resourceLocation; - -    public void buildGLThings() { -        previewTexture = new DynamicTexture(image); -        resourceLocation = Minecraft.getMinecraft().getTextureManager().getDynamicTextureLocation("dgurl/"+url, previewTexture); -    } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyManager.java b/src/main/java/kr/syeyoung/dungeonsguide/party/PartyManager.java index eaebc433..7382f203 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/party/PartyManager.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/party/PartyManager.java @@ -18,7 +18,7 @@  package kr.syeyoung.dungeonsguide.party; -import kr.syeyoung.dungeonsguide.RichPresenceManager; +import kr.syeyoung.dungeonsguide.rpc.RichPresenceManager;  import kr.syeyoung.dungeonsguide.DungeonsGuide;  import kr.syeyoung.dungeonsguide.events.HypixelJoinedEvent;  import kr.syeyoung.dungeonsguide.events.StompConnectedEvent; @@ -42,7 +42,6 @@ import org.json.JSONObject;  import java.security.SecureRandom;  import java.util.*;  import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.SynchronousQueue;  import java.util.function.Consumer;  public class PartyManager implements StompMessageHandler { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordActivity.java b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordActivity.java new file mode 100644 index 00000000..f25022f2 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordActivity.java @@ -0,0 +1,72 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.rpc; + +import kr.syeyoung.dungeonsguide.gamesdk.GameSDK; +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordActivity; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordActivityType; +import lombok.Data; + +@Data +public class JDiscordActivity { +    private EDiscordActivityType activityType; +    private long applicationId; +    private String name, state, details; +    private long start, end; +    private String largeImage, largeText, smallImage, smallText; +    private String partyId; +    private int partyCurr, partyMax; +    private String matchSecret, joinSecret, spectateSecret; +    private boolean instance; + +    public static JDiscordActivity fromJNA(DiscordActivity discordActivity) { +        if (discordActivity == null) return null; +        JDiscordActivity jDiscordActivity = new JDiscordActivity(); +        jDiscordActivity.activityType = discordActivity.activityType; +        jDiscordActivity.applicationId = discordActivity.applicationId.longValue(); +        jDiscordActivity.name = GameSDK.readString(discordActivity.name); +        jDiscordActivity.state = GameSDK.readString(discordActivity.state); +        jDiscordActivity.details = GameSDK.readString(discordActivity.details); +        if (discordActivity.assets != null) { +            jDiscordActivity.largeImage = GameSDK.readString(discordActivity.assets.large_image); +            jDiscordActivity.largeText = GameSDK.readString(discordActivity.assets.large_text); +            jDiscordActivity.smallImage = GameSDK.readString(discordActivity.assets.small_image); +            jDiscordActivity.smallText = GameSDK.readString(discordActivity.assets.small_text); +        } +        if (discordActivity.timestamps != null) { +            jDiscordActivity.start = discordActivity.timestamps.start.longValue(); +            jDiscordActivity.end = discordActivity.timestamps.end.longValue(); +        } +        if (discordActivity.secrets != null) { +            jDiscordActivity.matchSecret= GameSDK.readString(discordActivity.secrets.match); +            jDiscordActivity.joinSecret = GameSDK.readString(discordActivity.secrets.join); +            jDiscordActivity.spectateSecret = GameSDK.readString(discordActivity.secrets.spectate); +        } +        if (discordActivity.party != null) { +            jDiscordActivity.partyId = GameSDK.readString(discordActivity.party.id); +            if (discordActivity.party.discordActivityParty != null) { +                jDiscordActivity.partyCurr = discordActivity.party.discordActivityParty.current_size.intValue(); +                jDiscordActivity.partyMax = discordActivity.party.discordActivityParty.max_size.intValue(); +            } +        } +        jDiscordActivity.instance = discordActivity.instance; + +        return jDiscordActivity; +    } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordRelation.java b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordRelation.java new file mode 100644 index 00000000..3086c936 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordRelation.java @@ -0,0 +1,42 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.rpc; + +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordRelationship; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordRelationshipType; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordStatus; +import lombok.Data; + +@Data +public class JDiscordRelation { +    private EDiscordRelationshipType discordRelationshipType; +    private EDiscordStatus status; +    private JDiscordActivity discordActivity; +    private JDiscordUser discordUser; + +    public static JDiscordRelation fromJNA(DiscordRelationship relationship) { +        JDiscordRelation jDiscordRelation = new JDiscordRelation(); +        jDiscordRelation.discordUser = JDiscordUser.fromJNA(relationship.user); +        jDiscordRelation.discordActivity = JDiscordActivity.fromJNA(relationship.presence.activity); +        jDiscordRelation.status = relationship.presence.status; +        jDiscordRelation.discordRelationshipType = relationship.type; +        return jDiscordRelation; +    } + +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordUser.java b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordUser.java new file mode 100644 index 00000000..635ac405 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/rpc/JDiscordUser.java @@ -0,0 +1,40 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.rpc; + +import kr.syeyoung.dungeonsguide.gamesdk.GameSDK; +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordUser; +import lombok.Data; + +@Data +public class JDiscordUser { +    private long id; +    private String username, discriminator, avatar; +    private boolean bot; + +    public static JDiscordUser fromJNA(DiscordUser discordUser) { +        JDiscordUser jDiscordUser = new JDiscordUser(); +        jDiscordUser.id = discordUser.id.longValue(); +        jDiscordUser.username = GameSDK.readString(discordUser.username); +        jDiscordUser.discriminator = GameSDK.readString(discordUser.discriminator); +        jDiscordUser.avatar = GameSDK.readString(discordUser.avatar); +        jDiscordUser.bot = discordUser.bot; +        return jDiscordUser; +    } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/rpc/RichPresenceManager.java b/src/main/java/kr/syeyoung/dungeonsguide/rpc/RichPresenceManager.java new file mode 100644 index 00000000..23f8433d --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/rpc/RichPresenceManager.java @@ -0,0 +1,250 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021  cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.rpc; + +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; +import kr.syeyoung.dungeonsguide.events.DiscordUserJoinRequestEvent; +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.gamesdk.GameSDK; +import kr.syeyoung.dungeonsguide.gamesdk.jna.NativeGameSDK; +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.*; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.*; +import kr.syeyoung.dungeonsguide.gamesdk.jna.interfacestruct.*; +import kr.syeyoung.dungeonsguide.gamesdk.jna.typedef.*; +import kr.syeyoung.dungeonsguide.party.PartyManager; +import kr.syeyoung.dungeonsguide.stomp.StompHeader; +import kr.syeyoung.dungeonsguide.stomp.StompPayload; +import lombok.Getter; +import net.minecraftforge.common.MinecraftForge; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +public class RichPresenceManager implements Runnable { +    public static RichPresenceManager INSTANCE = new RichPresenceManager(); +    private Thread t = new Thread(this); + +    public RichPresenceManager() { +        t.start(); +    } +    @Getter +    private NativeGameSDK nativeGameSDK; +    @Getter +    private IDiscordCore iDiscordCore; +    private IDiscordActivityManager activityManager; +    private IDiscordRelationshipManager relationshipManager; +    private IDiscordActivityEvents.ByReference callbacks; +    private IDiscordRelationshipEvents.ByReference relation_callbacks; + +    @Getter +    private Map<Long, JDiscordRelation> relationMap = new HashMap<>(); + +    @Getter +    private int lastSetupCode = -99999; +    public int setup() { +        System.out.println("SETUP!!! "+ iDiscordCore); +        if (iDiscordCore != null) { +            System.out.println("DETROYED"); +            iDiscordCore.Destroy.destroy(iDiscordCore); +            activityManager = null; callbacks = null; relation_callbacks = null; relationMap.clear(); +        } + +        nativeGameSDK = GameSDK.getNativeGameSDK(); +        if (nativeGameSDK == null) return -9999; +        DiscordCreateParams discordCreateParams = new DiscordCreateParams(); +        discordCreateParams.flags = new UInt64(EDiscordCreateFlags.DiscordCreateFlags_Default.getValue()); +        discordCreateParams.client_id = new DiscordClientID(816298079732498473L); + +        callbacks = new IDiscordActivityEvents.ByReference(); +        callbacks.OnActivityInvite = (eventData, type, user, activity) -> { +            try { +                MinecraftForge.EVENT_BUS.post(new DiscordUserJoinRequestEvent(user, true)); +            } catch (Throwable t) { +                t.printStackTrace(); +            } +            System.out.println("Received Join Request from "+user.id.longValue()+" ("+GameSDK.readString(user.username)+")"); +        }; +        callbacks.OnActivityJoin = (eventData, secret) -> { +            DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload().method(StompHeader.SEND) +                .header("destination", "/app/party.askedtojoin") +                .payload(new JSONObject().put("token", secret).toString())); +            System.out.println("Trying to join with token "+secret); +        }; +        callbacks.OnActivityJoinRequest = (eventData, user) -> { +            try { +                MinecraftForge.EVENT_BUS.post(new DiscordUserJoinRequestEvent(user, false)); +            } catch (Throwable t) { +                t.printStackTrace(); +            } +                System.out.println("Received Join Request from "+user.id.longValue()+" - "+GameSDK.readString(user.username)); +        }; +        callbacks.OnActivitySpectate = (eventData, secret) -> { +        }; +        callbacks.write(); + +        relation_callbacks = new IDiscordRelationshipEvents.ByReference(); +        relation_callbacks.OnRefresh = (p) -> { +            IDiscordRelationshipManager iDiscordRelationshipManager = iDiscordCore.GetRelationshipManager.getRelationshipManager(iDiscordCore); +            iDiscordRelationshipManager.Filter.filter(iDiscordRelationshipManager, Pointer.NULL, (d, relation) -> true); +            IntByReference intByReference = new IntByReference(); +            iDiscordRelationshipManager.Count.count(iDiscordRelationshipManager, intByReference); +            int count = intByReference.getValue(); +            for (int i = 0; i < count; i++) { +                DiscordRelationship discordRelationship = new DiscordRelationship(); +                iDiscordRelationshipManager.GetAt.getAt(iDiscordRelationshipManager, new UInt32(i), discordRelationship); + +                JDiscordRelation jDiscordRelation = JDiscordRelation.fromJNA(discordRelationship); +                relationMap.put(jDiscordRelation.getDiscordUser().getId(), jDiscordRelation); +            } +        }; +        relation_callbacks.OnRelationshipUpdate = (p, rel) -> { +            JDiscordRelation jDiscordRelation = JDiscordRelation.fromJNA(rel); +            JDiscordRelation prev = relationMap.put(jDiscordRelation.getDiscordUser().getId(), jDiscordRelation); +            System.out.println("Discord relation update!! "+jDiscordRelation); +            try { +                MinecraftForge.EVENT_BUS.post(new DiscordUserUpdateEvent(prev, jDiscordRelation)); +            } catch (Throwable t) { +                t.printStackTrace(); +            } +        }; +        relation_callbacks.write(); + +        discordCreateParams.activity_events = callbacks; +        discordCreateParams.relationship_events = relation_callbacks; // 96 + +        PointerByReference pointerByReference = new PointerByReference(); +        discordCreateParams.write(); + +        EDiscordResult eDiscordResult = nativeGameSDK.DiscordCreate(new DiscordVersion(NativeGameSDK.DISCORD_VERSION), discordCreateParams, pointerByReference); +        if (eDiscordResult != EDiscordResult.DiscordResult_Ok) return eDiscordResult.getValue(); +        if (pointerByReference.getValue() == Pointer.NULL) return -9998; +        iDiscordCore = new IDiscordCore(pointerByReference.getValue()); + +        iDiscordCore.SetLogHook.setLogHook(iDiscordCore, EDiscordLogLevel.DiscordLogLevel_Debug, Pointer.NULL, new IDiscordCore.LogHook() { +            @Override +            public void hook(Pointer hookData, EDiscordLogLevel level, String message) { +                System.out.println(message+" - "+level+" - "+hookData); +            } +        }); + +        activityManager = iDiscordCore.GetActivityManager.getActivityManager(iDiscordCore); +        relationshipManager = iDiscordCore.GetRelationshipManager.getRelationshipManager(iDiscordCore); + +        return eDiscordResult.getValue(); +    } + +    private final SkyblockStatus skyblockStatus = DungeonsGuide.getDungeonsGuide().getSkyblockStatus(); + +    public void respond(DiscordSnowflake userID, EDiscordActivityJoinRequestReply reply) { +        activityManager.SendRequestReply.sendRequestReply(activityManager, userID, reply, Pointer.NULL, (callbackData, result) -> { +            System.out.println("Discord Returned "+result+" For Replying "+reply+" To "+userID.longValue()+"L"); +        }); +    } + +    public void accept(DiscordSnowflake userID) { +        activityManager.AcceptInvite.acceptInvite(activityManager, userID, Pointer.NULL, (callbackData, result) -> { +            System.out.println("Discord Returned "+result+" For Accepting invite from "+userID.longValue()+"L"); +        }); +    } +    public void updatePresence() { +        if (!skyblockStatus.isOnHypixel() || !FeatureRegistry.DISCORD_RICHPRESENCE.isEnabled() || (!skyblockStatus.isOnSkyblock() && FeatureRegistry.DISCORD_RICHPRESENCE.<Boolean>getParameter("disablenotskyblock").getValue())) { +            activityManager.ClearActivity.clearActivity(activityManager, Pointer.NULL, new NativeGameSDK.DiscordCallback() { +                @Override +                public void callback(Pointer callbackData, EDiscordResult result) { +                } +            }); +        } else { +            String name = skyblockStatus.getDungeonName() == null ? "" : skyblockStatus.getDungeonName(); +            if (!skyblockStatus.isOnSkyblock()) name ="Somewhere on Hypixel"; +            if (name.trim().equals("Your Island")) name = "Private Island"; + +            DiscordActivity latestDiscordActivity = new DiscordActivity(); +            latestDiscordActivity.assets = new DiscordActivityAssets(); +            latestDiscordActivity.secrets = new DiscordActivitySecrets(); +            latestDiscordActivity.party = new DiscordActivityParty(); +            latestDiscordActivity.party.discordActivityParty = new DiscordPartySize(); +            latestDiscordActivity.timestamps = new DiscordActivityTimestamps(); +            GameSDK.writeString(latestDiscordActivity.assets.large_image, "mort"); +            GameSDK.writeString(latestDiscordActivity.assets.large_text, "mort"); +            GameSDK.writeString(latestDiscordActivity.state, name); + +                GameSDK.writeString(latestDiscordActivity.party.id, PartyManager.INSTANCE.getPartyID() == null ? "" : PartyManager.INSTANCE.getPartyID()); +                latestDiscordActivity.party.discordActivityParty.current_size = new Int32(PartyManager.INSTANCE.getMemberCount()); +                latestDiscordActivity.party.discordActivityParty.max_size = new Int32(PartyManager.INSTANCE.getMaxParty()); + +            if (skyblockStatus.getContext() != null) { +                DungeonContext dungeonContext = skyblockStatus.getContext(); +                long init = dungeonContext.getInit(); +                latestDiscordActivity.timestamps.start = new DiscordTimestamp(init); + +                if (dungeonContext.getBossfightProcessor() != null) { +                    GameSDK.writeString(latestDiscordActivity.details, "Fighting "+dungeonContext.getBossfightProcessor().getBossName()+": "+dungeonContext.getBossfightProcessor().getCurrentPhase()); +                } else { +                    GameSDK.writeString(latestDiscordActivity.details, "Clearing Rooms"); +                } +            } else { +                latestDiscordActivity.timestamps.start = new DiscordTimestamp(0); +                GameSDK.writeString(latestDiscordActivity.details, "Dungeons Guide"); +            } +            if (PartyManager.INSTANCE.isAllowAskToJoin()) { +                GameSDK.writeString(latestDiscordActivity.secrets.join, PartyManager.INSTANCE.getAskToJoinSecret()); +            } else { +                GameSDK.writeString(latestDiscordActivity.secrets.join, ""); +            } +            activityManager.UpdateActivity.updateActivity(activityManager, latestDiscordActivity, Pointer.NULL, new NativeGameSDK.DiscordCallback() { +                @Override +                public void callback(Pointer callbackData, EDiscordResult result) { +                } +            }); +        } +    } + +    @Override +    public void run() { +        boolean setup = true; +        int counter = 0; +        while(!Thread.interrupted()) { +            try { +                if (iDiscordCore == null || setup) { +                    lastSetupCode = setup(); +                    System.out.println("Discord returned "+lastSetupCode+" for setup "+EDiscordResult.fromValue(lastSetupCode)); +                    setup = lastSetupCode != EDiscordResult.DiscordResult_Ok.getValue(); +                    counter = 0; +                } else { +                    EDiscordResult eDiscordResult = iDiscordCore.RunCallbacks.runCallbacks(iDiscordCore); +                    if (eDiscordResult == EDiscordResult.DiscordResult_NotRunning) { +                        setup = true; +                    } else { +                        if (counter == 0) +                            updatePresence(); +                        if (++counter == 15) counter = 0; +                    } +                } +                Thread.sleep(16L); +            } catch (Exception e) {e.printStackTrace();} +        } +    } +} | 
