// Reference: Humanlights.System // Requires: RusterNET using Humanlights.Components; using Humanlights.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Oxide.Core; using Oxide.Core.Plugins; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using UnityEngine; namespace Oxide.Plugins { [Info ( "Ruster.Addons", "Raul-Sorin Sorban", "1.0.3" )] [Description ( "Tool and API system for Ruster.NET. Addon creation and execution." )] public class RusterAddons : RustPlugin { #region Logging public void Log ( object message, int level = 1 ) { if ( level >= NET.Config.LogLevel && message != null ) Puts ( message.ToString () ); } public bool LogException ( bool doTrigger, string message, bool log = true ) { if ( !doTrigger ) return false; if ( log ) Log ( $"Exception: {message}" ); return true; } #endregion #region Plugins public RusterNET NET { get; private set; } public void RefreshPlugins () { if ( NET == null || !NET.IsLoaded ) NET = plugins.Find ( "RusterNET" ) as RusterNET; } #endregion #region Overrides private void OnServerInitialized () { RefreshPlugins (); if ( ConVar.Server.hostname.ToLower ().Contains ( "test" ) ) GenerateDocumentation (); } private void OnPluginLoaded ( Plugin name ) { RefreshPlugins (); } private void OnPluginUnloaded ( Plugin name ) { RefreshPlugins (); } #endregion #region Parsing public JObject ToParse ( T value ) { return JsonConvert.DeserializeObject ( JsonConvert.SerializeObject ( value ) ); } public T FromParse ( JObject value ) { return value.ToObject (); } public string GetHookName ( string nameof ) { return nameof.Replace ( "RNETAPI_", "" ); } #endregion #region API [API ( Category = APIAttribute.Categories.General, Description = "It does or does not answer our humanity's most asked question.", Returns = "Game crash.", Example = "var isJamieLeeOrJackieChan = true;\n[CALL]\nPuts ( call );\nthrow new Exception ( \"This is some stupid insanity.\" );" )] [HookMethod ( nameof ( IsBlockedTonite ) )] public string IsBlockedTonite ( bool isJamieLeeOrJackieChan ) { if ( isJamieLeeOrJackieChan ) return "YEEEEEEEEEEEEEHHHHHHH"; return "no"; } #region General [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Community feed setup.", Returns = "Returns the Community Feed-ID." )] [HookMethod ( nameof ( GetCommunityFeedId ) )] public ulong GetCommunityFeedId () { return RusterNET.CommunityFeedId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Marketplace feed setup.", Returns = "Returns the Marketplace Feed-ID." )] [HookMethod ( nameof ( GetMarketplaceFeedId ) )] public ulong GetMarketplaceFeedId () { return RusterNET.MarketplaceFeedId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Blackmarket feed setup.", Returns = "Returns the Blackmarket Feed-ID." )] [HookMethod ( nameof ( GetBlackmarketFeedId ) )] public ulong GetBlackmarketFeedId () { return RusterNET.BlackmarketFeedId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the RedRoom feed setup.", Returns = "Returns the RedRoom Feed-ID." )] [HookMethod ( nameof ( GetRedRoomFeedId ) )] public ulong GetRedRoomFeedId () { return RusterNET.RedRoomFeedId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster workshop skin ID.", Returns = "Returns the Ruster workshop skin ID." )] [HookMethod ( nameof ( GetRusterSkinId ) )] public ulong GetRusterSkinId () { return RusterNET.Instance.GetProConfig ( nameof ( RusterNET.RusterSkinId ), RusterNET.RusterSkinId ); } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Marketplace 24h Advert workshop skin ID.", Returns = "Returns the Ruster Marketplace 24h Advert workshop skin ID." )] [HookMethod ( nameof ( GetRusterMarketplace24hAdvertSkinId ) )] public ulong GetRusterMarketplace24hAdvertSkinId () { return RusterNET.Instance.GetProConfig ( nameof ( RusterNET.RusterMarketplace24hAdvertSkinId ), RusterNET.RusterMarketplace24hAdvertSkinId ); } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Marketplace 1w Advert workshop skin ID.", Returns = "Returns the Ruster Marketplace 1w Advert workshop skin ID." )] [HookMethod ( nameof ( GetRusterMarketplace1wAdvertSkinId ) )] public ulong GetRusterMarketplace1wAdvertSkinId () { return RusterNET.Instance.GetProConfig ( nameof ( RusterNET.RusterMarketplace1wAdvertSkinId ), RusterNET.RusterMarketplace1wAdvertSkinId ); } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Business Card workshop skin ID.", Returns = "Returns the Ruster Business Card workshop skin ID." )] [HookMethod ( nameof ( GetRusterBusinessCardSkinId ) )] public ulong GetRusterBusinessCardSkinId () { return RusterNET.Instance.GetProConfig ( nameof ( RusterNET.RusterBusinessCardSkinId ), RusterNET.RusterBusinessCardSkinId ); } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Short Flipbook workshop skin ID.", Returns = "Returns the Ruster Short Flipbook workshop skin ID." )] [HookMethod ( nameof ( GetRusterShortFlipbookSkinId ) )] public ulong GetRusterShortFlipbookSkinId () { return RusterNET.RusterShortFlipbookSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Medium Flipbook workshop skin ID.", Returns = "Returns the Ruster Medium Flipbook workshop skin ID." )] [HookMethod ( nameof ( GetRusterMediumFlipbookSkinId ) )] public ulong GetRusterMediumFlipbookSkinId () { return RusterNET.RusterMediumFlipbookSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Long Flipbook workshop skin ID.", Returns = "Returns the Ruster Long Flipbook workshop skin ID." )] [HookMethod ( nameof ( GetRusterLongFlipbookSkinId ) )] public ulong GetRusterLongFlipbookSkinId () { return RusterNET.RusterLongFlipbookSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Legit Lottery Ticket workshop skin ID.", Returns = "Returns the Ruster Legit Lottery Ticket workshop skin ID." )] [HookMethod ( nameof ( GetRusterLegitLotteryTicketSkinId ) )] public ulong GetRusterLegitLotteryTicketSkinId () { return RusterNET.RusterLegitLotteryTicketSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Lucky-Charm Lottery Ticket workshop skin ID.", Returns = "Returns the Ruster Lucky-Charm Lottery Ticket workshop skin ID." )] [HookMethod ( nameof ( GetRusterLuckyCharmLotteryTicketSkinId ) )] public ulong GetRusterLuckyCharmLotteryTicketSkinId () { return RusterNET.RusterLuckyCharmLotteryTicketSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Iconic Lottery Ticket workshop skin ID.", Returns = "Returns the Ruster Iconic Lottery Ticket workshop skin ID." )] [HookMethod ( nameof ( GetRusterIconicLotteryTicketSkinId ) )] public ulong GetRusterIconicLotteryTicketSkinId () { return RusterNET.RusterIconicLotteryTicketSkinId; } [API ( Category = APIAttribute.Categories.General, Description = "Used for grabbing the Ruster Gift-Card workshop skin ID.", Returns = "Returns the Ruster Gift-Card workshop skin ID." )] [HookMethod ( nameof ( GetRusterGiftCardSkinId ) )] public ulong GetRusterGiftCardSkinId () { return RusterNET.RusterGiftCardSkinId; } #endregion #region User [API ( Category = APIAttribute.Categories.User, Description = "Gets all users.", Returns = "Returns all users in the server." )] [HookMethod ( nameof ( GetUsers ) )] public ulong [] GetUsers () { return NET.Data.Users.Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets user.", Returns = "Returns user in the server." )] [HookMethod ( nameof ( GetUser ) )] public JObject GetUser ( ulong id ) { return ToParse ( NET.Data.GetUser ( id ) ); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is an administrator on Ruster.NET.", Returns = "Is user an admin?" )] [HookMethod ( nameof ( IsAdmin ) )] public bool IsAdmin ( ulong userId ) { return NET.Data.GetUser ( userId ).IsAdmin (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is a moderator on Ruster.NET.", Returns = "Is user a moderator?" )] [HookMethod ( nameof ( IsModerator ) )] public bool IsModerator ( ulong userId ) { return NET.Data.GetUser ( userId ).IsModerator (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is verified on Ruster.NET.", Returns = "Is user verified?" )] [HookMethod ( nameof ( IsVerified ) )] public bool IsVerified ( ulong userId ) { return NET.Data.GetUser ( userId ).IsVerified (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is a developer on Ruster.NET.", Returns = "Is user a developer?" )] [HookMethod ( nameof ( IsDeveloper ) )] public bool IsDeveloper ( ulong userId ) { return NET.Data.GetUser ( userId ).IsDeveloper (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is a bot on Ruster.NET.", Returns = "Is user a bot?" )] [HookMethod ( nameof ( IsBot ) )] public bool IsBot ( ulong userId ) { return NET.Data.GetUser ( userId ).IsBot; } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is marked as dead on Ruster.NET.", Returns = "Is user dead?" )] [HookMethod ( nameof ( IsDead ) )] public bool IsDead ( ulong userId ) { return NET.Data.GetUser ( userId ).IsDead (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user is marked as online on Ruster.NET.", Returns = "Is user online?" )] [HookMethod ( nameof ( IsOnline ) )] public bool IsOnline ( ulong userId ) { return NET.Data.GetUser ( userId ).IsOnline (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if two users are friends on Ruster.NET.", Returns = "Are users friends?" )] [HookMethod ( nameof ( IsFriend ) )] public bool IsFriend ( ulong userId, ulong otherUserId ) { return NET.Data.GetUser ( userId ).IsFriends ( otherUserId ); } [API ( Category = APIAttribute.Categories.User, Description = "Properly formatted user display name as seen on Ruster.NET.", Returns = "The display name of an user." )] [HookMethod ( nameof ( GetDisplayName ) )] public string GetDisplayName ( ulong userId, bool coloured = true ) { return NET.Data.GetUser ( userId ).GetDisplayName ( coloured ); } [API ( Category = APIAttribute.Categories.User, Description = "Username as seen on Ruster.NET.", Returns = "The username of an user." )] [HookMethod ( nameof ( GetUsername ) )] public string GetUsername ( ulong userId ) { return NET.Data.GetUser ( userId ).GetUsername (); } [API ( Category = APIAttribute.Categories.User, Description = "Language an user has set for their account on Ruster.NET.", Returns = "The language of an user." )] [HookMethod ( nameof ( GetLanguage ) )] public string GetLanguage ( ulong userId ) { return NET.Data.GetUser ( userId ).Configuration.Language; } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of SteamIDs of an user's friends on Ruster.NET.", Returns = "The friends list of an user." )] [HookMethod ( nameof ( GetFriends ) )] public ulong [] GetFriends ( ulong userId ) { return NET.Data.GetUser ( userId ).GetFriends ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of SteamIDs of an user's blocked accounts on Ruster.NET.", Returns = "The blocked list of an user." )] [HookMethod ( nameof ( GetBlockedUsers ) )] public ulong [] GetBlockedUsers ( ulong userId ) { return NET.Data.GetUser ( userId ).GetBlockedPlayers ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of IDs of published posts for an user on Ruster.NET.", Returns = "The posts list of an user." )] [HookMethod ( nameof ( GetPosts ) )] public int [] GetPosts ( ulong userId ) { return NET.Data.GetUser ( userId ).GetPosts ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of IDs of published store posts for an user on Ruster.NET.", Returns = "The store posts list of an user." )] [HookMethod ( nameof ( GetStorePosts ) )] public int [] GetStorePosts ( ulong userId ) { return NET.Data.GetUser ( userId ).GetStorePosts ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of IDs of published Marketplace posts for an user on Ruster.NET.", Returns = "The Marketplace posts list of an user." )] [HookMethod ( nameof ( GetMarketplacePosts ) )] public int [] GetMarketplacePosts ( ulong userId ) { return NET.Data.GetUser ( userId ).GetMarketplacePosts ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of IDs of published Advert posts for an user on Ruster.NET.", Returns = "The Advert posts list of an user." )] [HookMethod ( nameof ( GetAdvertPosts ) )] public int [] GetAdvertPosts ( ulong userId ) { return NET.Data.GetUser ( userId ).GetAdvertPosts ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of SteamIDs for an user's received friend requests on Ruster.NET.", Returns = "The received friend requests SteamID list of an user." )] [HookMethod ( nameof ( GetReceivedFriendRequests ) )] public ulong [] GetReceivedFriendRequests ( ulong userId ) { return NET.Data.GetUser ( userId ).GetReceivedFriendRequests ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Gets a list of SteamIDs for an user's sent friend requests on Ruster.NET.", Returns = "The sent friend requests SteamID list of an user." )] [HookMethod ( nameof ( GetSentFriendRequests ) )] public ulong [] GetSentFriendRequests ( ulong userId ) { return NET.Data.GetUser ( userId ).GetSentFriendRequests ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if an user blocked another user on Ruster.NET.", Returns = "Is other user blocked by user?" )] [HookMethod ( nameof ( HasBlocked ) )] public bool HasBlocked ( ulong userId, ulong otherUserId ) { return NET.Data.GetUser ( userId ).HasBlocked ( otherUserId ); } [API ( Category = APIAttribute.Categories.User, Description = "Checks if two users have their communication blocked on Ruster.NET.", Returns = "Are two users communication blocked?" )] [HookMethod ( nameof ( HasBlockedCommunication ) )] public bool HasBlockedCommunication ( ulong userId, ulong otherUserId ) { return NET.Data.GetUser ( userId ).HasBlockedCommunication ( otherUserId ); } [API ( Category = APIAttribute.Categories.User, Description = "If an user isn't friends with someone, a request will be sent their way and will be notified.", Returns = "Request sent or not." )] [HookMethod ( nameof ( AddFriend ) )] public bool AddFriend ( ulong userId, ulong otherUserId ) { var user = NET.Data.GetUser ( userId ); var otherUser = NET.Data.GetUser ( otherUserId ); if ( user.IsFriends ( otherUserId ) ) return false; return NET.Data.SendFriendRequest ( user, otherUser ); } [API ( Category = APIAttribute.Categories.User, Description = "Handling a friend request, will accept/reject an existent friend request sent by the user.", Returns = "Request sent or not." )] [HookMethod ( nameof ( HandleFriendRequest ) )] public bool HandleFriendRequest ( ulong userId, ulong otherUserId, bool doAccept ) { var user = NET.Data.GetUser ( userId ); var otherUser = NET.Data.GetUser ( otherUserId ); if ( !NET.Data.HasFriendRequestSent ( user, otherUser ) ) return false; NET.Data.HandleFriendRequest ( doAccept, user, otherUser ); return true; } [API ( Category = APIAttribute.Categories.User, Description = "If an user is friends with someone, they'll be removed from both users' lists.", Returns = "Has removed friend or not." )] [HookMethod ( nameof ( RemoveFriend ) )] public bool RemoveFriend ( ulong userId, ulong otherUserId ) { var user = NET.Data.GetUser ( userId ); var otherUser = NET.Data.GetUser ( otherUserId ); if ( !user.IsFriends ( otherUserId ) ) return false; NET.Data.RemoveFriend ( user, otherUser ); return true; } [API ( Category = APIAttribute.Categories.User, Description = "Creates or updates an user with the input information (must come with the ID).", Returns = "The user from the database." )] [HookMethod ( nameof ( CreateOrUpdateUser ) )] public JObject CreateOrUpdateUser ( JObject user, bool overrideProperties = true ) { var userData = FromParse ( user ); var newUser = NET.Data.GetUser ( userData.Id ); if ( NET.Data.UserExists ( userData.Id ) && !overrideProperties ) return ToParse ( newUser ); newUser.AvatarUrl = userData.AvatarUrl; newUser.TimezoneOffset = userData.TimezoneOffset; newUser.CurrentDisplayName = userData.CurrentDisplayName; newUser.CustomDisplayName = userData.CustomDisplayName; newUser.Wallet = userData.Wallet; newUser.Friends = userData.Friends; newUser.Blocked = userData.Blocked; newUser.IsBot = userData.IsBot; newUser.Configuration = userData.Configuration; return ToParse ( newUser ); } [API ( Category = APIAttribute.Categories.User, Description = "Gives a business card to a player with the user's credentials.", Returns = null )] [HookMethod ( nameof ( GiveBusinessCard ) )] public void GiveBusinessCard ( BasePlayer player, ulong userId ) { NET.GiveBusinessCard ( player, userId ); } #endregion #region Post [API ( Category = APIAttribute.Categories.Post, Description = "Checks if a post provided with an ID is an advertisment in Ruster.NET.", Returns = "Is post an advert or not?" )] [HookMethod ( nameof ( IsAdvert ) )] public bool IsAdvert ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.IsAdvert (); } [API ( Category = APIAttribute.Categories.Post, Description = "Checks if a post provided with an ID is a Marketplace listing in Ruster.NET.", Returns = "Is post a Marketplace listing or not?" )] [HookMethod ( nameof ( IsMarketplaceListing ) )] public bool IsMarketplaceListing ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.IsMarketplaceListing (); } [API ( Category = APIAttribute.Categories.Post, Description = "When the post is an advertisment, checks if a post provided with an ID is overdue its duration in Ruster.NET.", Returns = "Is advert overdue or not?" )] [HookMethod ( nameof ( IsOverdue ) )] public bool IsOverdue ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.IsOverdue (); } [API ( Category = APIAttribute.Categories.Post, Description = "Checks if a post provided with an ID a reply to a parent thread or not.", Returns = "Is post a reply or not?" )] [HookMethod ( nameof ( IsReply ) )] public bool IsReply ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.IsReply (); } [API ( Category = APIAttribute.Categories.Post, Description = "Checks if an user has liked a post provided with the ID or not.", Returns = "Has user liked the post or not?" )] [HookMethod ( nameof ( HasLiked ) )] public bool HasLiked ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.HasLiked ( NET.Data.GetUser ( userId ) ); } [API ( Category = APIAttribute.Categories.Post, Description = "Checks if an user has disliked a post provided with the ID or not.", Returns = "Has user disliked the post or not?" )] [HookMethod ( nameof ( HasDisliked ) )] public bool HasDisliked ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.HasDisliked ( NET.Data.GetUser ( userId ) ); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets the content of a post.", Returns = "The content of a post." )] [HookMethod ( nameof ( GetContent ) )] public string GetContent ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return post.GetContent (); } [API ( Category = APIAttribute.Categories.Post, Description = "If the post is an advertisment, it'll return the time left 'till it's overdue.", Returns = "The advert time left 'till it's overdue." )] [HookMethod ( nameof ( GetAdvertTimeLeft ) )] public float GetAdvertTimeLeft ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return 0f; return post.AdvertTimeLeft (); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets all the hashtags (custom or auto-generated) of a post.", Returns = "Post hashtags." )] [HookMethod ( nameof ( GetHashtags ) )] public JObject [] GetHashtags ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return post.GetHashtags ().Select ( x => ToParse ( x ) ).ToArray (); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets a list the like Steam IDs of a post.", Returns = "Post likes." )] [HookMethod ( nameof ( GetLikes ) )] public ulong [] GetLikes ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return post.GetLikes ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets a list the dislike Steam IDs of a post.", Returns = "Post dislikes." )] [HookMethod ( nameof ( GetDislikes ) )] public ulong [] GetDislikes ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return post.GetDislikes ().Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets the author of a post with the provided post ID.", Returns = "Database user." )] [HookMethod ( nameof ( GetAuthor ) )] public JObject GetAuthor ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return ToParse ( post.GetUser () ); } [API ( Category = APIAttribute.Categories.Post, Description = "Gets the parent feed of a post with the provided post ID.", Returns = "The feed ID of where the post has been published into." )] [HookMethod ( nameof ( GetFeed ) )] public ulong GetFeed ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return 0ul; var feed = post.GetFeed (); if ( LogException ( feed == null, $"The post[{postId}] feed does not exist." ) ) return 0ul; return feed.Id; } [API ( Category = APIAttribute.Categories.Post, Description = "Gets the parent feed type of a post with the provided post ID.", Returns = "The feed type of where the post has been published into." )] [HookMethod ( nameof ( GetPostType ) )] public string GetPostType ( int postId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return null; return post.GetPostType (); } [API ( Category = APIAttribute.Categories.Post, Description = "Can the given user get the listing post item for free?", Returns = null )] [HookMethod ( nameof ( CanGetForFree ) )] public bool CanGetForFree ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.CanGetForFree ( NET.Data.GetUser ( userId ) ); } [API ( Category = APIAttribute.Categories.Post, Description = "Can the given user buy the listing post item?", Returns = null )] [HookMethod ( nameof ( CanBuy ) )] public bool CanBuy ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); if ( LogException ( post == null, $"The post[{postId}] does not exist." ) ) return false; return post.CanBuy ( NET.Data.GetUser ( userId ) ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to like a post with the given user.", Returns = "The post has been liked." )] [HookMethod ( nameof ( LikePost ) )] public bool LikePost ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); var user = NET.Data.GetUser ( userId ); if ( LogException ( post == null, "The postID is not valid." ) || LogException ( post.HasLiked ( user ), "The post has already been liked by this user." ) ) return false; post.Like ( user ); return true; } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to like a post with the given user.", Returns = "The post has been liked." )] [HookMethod ( nameof ( LikePost ) )] public bool LikePost ( JObject post, ulong userId ) { return LikePost ( ( ( string )post [ "Id" ] ).ToInt (), userId ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to dislike a post with the given user.", Returns = "The post has been disliked." )] [HookMethod ( nameof ( DislikePost ) )] public bool DislikePost ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); var user = NET.Data.GetUser ( userId ); if ( LogException ( post == null, "The postID is not valid." ) || LogException ( post.HasDisliked ( user ), "The post has already been disliked by this user." ) ) return false; post.Dislike ( user ); return true; } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to dislike a post with the given user.", Returns = "The post has been disliked." )] [HookMethod ( nameof ( DislikePost ) )] public bool DislikePost ( JObject post, ulong userId ) { return DislikePost ( ( ( string )post [ "Id" ] ).ToInt (), userId ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to remove a like or dislike from a post with the given user.", Returns = "Has removed like or dislike from post." )] [HookMethod ( nameof ( RemoveLikeOrDislikePost ) )] public bool RemoveLikeOrDislikePost ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); var user = NET.Data.GetUser ( userId ); if ( LogException ( post == null, "The postID is not valid." ) ) return false; if ( post.HasLiked ( user ) ) { post.Like ( user ); return true; } else if ( post.HasDisliked ( user ) ) { post.Dislike ( user ); return true; } return false; } [API ( Category = APIAttribute.Categories.Post, Description = "Attemtps to remove a like or dislike from a post with the given user.", Returns = "Has removed like or dislike from post." )] [HookMethod ( nameof ( RemoveLikeOrDislikePost ) )] public bool RemoveLikeOrDislikePost ( JObject post, ulong userId ) { return RemoveLikeOrDislikePost ( ( ( string )post [ "Id" ] ).ToInt (), userId ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attempts to pin a post on the parent feed.", Returns = "The post has been pinned." )] [HookMethod ( nameof ( PinPost ) )] public bool PinPost ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); var user = NET.Data.GetUser ( userId ); if ( LogException ( post == null, "The postID is not valid." ) || LogException ( post.IsPinned, "The post has already been pinned." ) ) return false; return post.Pin ( user, post.GetFeed () ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attempts to pin a post on the parent feed.", Returns = "The post has been pinned." )] [HookMethod ( nameof ( PinPost ) )] public bool PinPost ( JObject post, ulong userId ) { return PinPost ( ( ( string )post [ "Id" ] ).ToInt (), userId ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attempts to unpin a post from the parent feed.", Returns = "The post has been unpinned." )] [HookMethod ( nameof ( UnpinPost ) )] public bool UnpinPost ( int postId, ulong userId ) { var post = NET.Data.GetPost ( postId ); var user = NET.Data.GetUser ( userId ); if ( LogException ( post == null, "The postID is not valid." ) || LogException ( post.IsPinned, "The post is not pinned." ) ) return false; return post.Unpin ( user, post.GetFeed () ); } [API ( Category = APIAttribute.Categories.Post, Description = "Attempts to unpin a post from the parent feed.", Returns = "The post has been unpinned." )] [HookMethod ( nameof ( UnpinPost ) )] public bool UnpinPost ( JObject post, ulong userId ) { return UnpinPost ( ( ( string )post [ "Id" ] ).ToInt (), userId ); } #endregion #region Feed [API ( Category = APIAttribute.Categories.Feed, Description = "Gets the title of a feed with id.", Returns = "Feed title." )] [HookMethod ( nameof ( GetFeedTitle ) )] public string GetFeedTitle ( ulong feedId ) { var feed = NET.Data.GetFeed ( feedId ); if ( feed == null ) return string.Empty; return feed.GetFeedTitle (); } [API ( Category = APIAttribute.Categories.Feed, Description = "Gets the type of a feed with id.", Returns = "Feed type." )] [HookMethod ( nameof ( GetFeedType ) )] public int GetFeedType ( ulong feedId ) { var feed = NET.Data.GetFeed ( feedId ); if ( feed == null ) return -1; return ( int )feed.GetFeedType (); } [API ( Category = APIAttribute.Categories.Feed, Description = "Checks if the user can post in a feed or not.", Returns = "Can post in the feed or not." )] [HookMethod ( nameof ( CanPost ) )] public bool CanPost ( ulong feedId, ulong userId ) { var feed = NET.Data.GetFeed ( feedId ); if ( feed == null ) return false; return feed.CanPost ( userId ); } [API ( Category = APIAttribute.Categories.Feed, Description = "Can user delete the post or not.", Returns = "User can delete." )] [HookMethod ( nameof ( CanDelete ) )] public bool CanDelete ( ulong feedId, ulong userId, int postId ) { var feed = NET.Data.GetFeed ( feedId ); if ( feed == null ) return false; return feed.CanDelete ( userId, postId ); } [API ( Category = APIAttribute.Categories.Feed, Description = "Get the owner of the feed (if any).", Returns = "Feed owner." )] [HookMethod ( nameof ( GetOwner ) )] public JObject GetOwner ( ulong feedId ) { return ToParse ( NET.Data.GetFeed ( feedId )?.GetOwner () ); } [API ( Category = APIAttribute.Categories.Feed, Description = "Get all the hashtags from feed with id.", Returns = "Feed hashtags." )] [HookMethod ( nameof ( GetHashtags ) )] public JObject [] GetHashtags ( ulong feedId ) { return NET.Data.GetFeed ( feedId )?.GetHashtags ().Select ( x => ToParse ( x ) ).ToArray (); } [API ( Category = APIAttribute.Categories.Feed, Description = "Is a community feed or not.", Returns = "Is community feed." )] [HookMethod ( nameof ( IsCommunity ) )] public bool IsCommunity ( ulong feedId ) { return NET.Data.GetFeed ( feedId ).IsCommunity (); } [API ( Category = APIAttribute.Categories.Feed, Description = "Is a marketplace feed or not.", Returns = "Is marketplace feed." )] [HookMethod ( nameof ( IsMarketplace ) )] public bool IsMarketplace ( ulong feedId ) { return NET.Data.GetFeed ( feedId ).IsMarketplace (); } [API ( Category = APIAttribute.Categories.Feed, Description = "Creates a post and publishes it onto a feed.", Returns = "Returns the published post." )] [HookMethod ( nameof ( CreatePost ) )] public JObject CreatePost ( ulong feedId, ulong authorId, JObject post ) { var feed = NET.Data.GetFeed ( feedId ); if ( LogException ( feed == null, "The feedID is not valid." ) ) return null; var author = NET.Data.GetUser ( authorId ); var postData = FromParse ( post ); var newPost = RusterNET.RusterFeed.RusterPost.Create ( author, postData.Content ); newPost.PhotoUrl = postData.PhotoUrl; newPost.PhotoTag = postData.PhotoTag; newPost.CassetteId = postData.CassetteId; newPost.CassetteTitle = postData.CassetteTitle; newPost.Advert = postData.Advert; newPost.MarketplaceListing = postData.MarketplaceListing; if ( postData.Location != null ) newPost.Location = postData.Location; newPost.Publish ( feed ); return ToParse ( newPost ); } [API ( Category = APIAttribute.Categories.Feed, Description = "Deletes a post from feed.", Returns = "Returns the result (could be a reason of why it didn't get removed)." )] [HookMethod ( nameof ( DeletePost ) )] public string DeletePost ( ulong feedId, int postId ) { var reason = string.Empty; NET.Data.GetFeed ( feedId ).Delete ( postId, out reason ); return reason; } #endregion #region DM [API ( Category = APIAttribute.Categories.DM, Description = "Gets or creates a conversation with someone.", Returns = "Returns the ID of the conversation created / found." )] [HookMethod ( nameof ( GetOrCreateConversation ) )] public int GetOrCreateConversation ( ulong creatorId, ulong otherId ) { var creator = NET.Data.GetUser ( otherId ); var conversation = creator.GetConversation ( creatorId ); if ( !conversation.ViewerList.Contains ( otherId ) ) conversation.ViewerList.Add ( otherId ); return conversation.Id; } [API ( Category = APIAttribute.Categories.DM, Description = "Get all users in the conversation.", Returns = "Returns users." )] [HookMethod ( nameof ( GetConversationUserIds ) )] public ulong [] GetConversationUserIds ( int conversationId ) { var conversation = NET.Data.GetConversation ( conversationId ); return conversation.Users?.ToArray (); } [API ( Category = APIAttribute.Categories.DM, Description = "Get all users in the conversation.", Returns = "Returns users." )] [HookMethod ( nameof ( GetConversationUsers ) )] public JObject [] GetConversationUsers ( int conversationId ) { var conversation = NET.Data.GetConversation ( conversationId ); return conversation.Users?.Select ( x => ToParse ( RusterNET.Instance.Data.GetUser ( x ) ) ).ToArray (); } [API ( Category = APIAttribute.Categories.DM, Description = "Sends a message into a conversation, notifying viewers of the conversation.", Returns = "Returns the published message." )] [HookMethod ( nameof ( SendMessage ) )] public JObject SendMessage ( int conversationId, JObject message ) { var conversation = NET.Data.GetConversation ( conversationId ); var newMessage = FromParse ( message ); newMessage.Id = RusterNET.RusterConversation.RusterDirectMessage.GetId ( conversation ); conversation.PostMessage ( newMessage ); return ToParse ( newMessage ); } [API ( Category = APIAttribute.Categories.DM, Description = "Gets messages with an amount from a conversation. Use -1 amount to get ALL messages.", Returns = "Message IDs." )] [HookMethod ( nameof ( GetMessages ) )] public int [] GetMessages ( int conversationId, int amount ) { var conversation = NET.Data.GetConversation ( conversationId ); return ( amount == -1 ? conversation.Messages : conversation.Messages.Take ( amount ) ).Select ( x => x.Id ).ToArray (); } [API ( Category = APIAttribute.Categories.DM, Description = "Deletes a message from a conversation.", Returns = "Returns true if the message has been removed." )] [HookMethod ( nameof ( DeleteMessage ) )] public bool DeleteMessage ( int conversationId, int messageId ) { var conversation = NET.Data.GetConversation ( conversationId ); var anyMessages = conversation.Messages.Any ( x => x.Id == messageId ); conversation.Messages.RemoveAll ( x => x.Id == messageId ); return anyMessages; } [API ( Category = APIAttribute.Categories.DM, Description = "Deletes all messages from a conversation.", Returns = "Returns the amount of purged messages." )] [HookMethod ( nameof ( PurgeConversation ) )] public int PurgeConversation ( int conversationId ) { var conversation = NET.Data.GetConversation ( conversationId ); var count = conversation.Messages.Count; conversation.Messages.Clear (); return count; } [API ( Category = APIAttribute.Categories.DM, Description = "Marks a message as read or not.", Returns = "Nothing." )] [HookMethod ( nameof ( MarkMessage ) )] public void MarkMessage ( int conversationId, int messageId, bool read ) { var conversation = NET.Data.GetConversation ( conversationId ); var message = conversation.GetMessage ( messageId ); message.Status = read ? RusterNET.RusterConversation.RusterDirectMessage.StatusTypes.Read : RusterNET.RusterConversation.RusterDirectMessage.StatusTypes.Sent; } #endregion #region Browser [API ( Category = APIAttribute.Categories.Browser, Description = "Opens the browser for a specific player." )] [HookMethod ( nameof ( OpenBrowser ) )] public void OpenBrowser ( ulong userId ) { NET.Launch ( userId ); } [API ( Category = APIAttribute.Categories.Browser, Description = "Closes the browser for a specific player." )] [HookMethod ( nameof ( OpenBrowser ) )] public void CloseBrowser ( ulong userId ) { var browser = NET.GetBrowser ( userId ); browser.CloseFully (); } [API ( Category = APIAttribute.Categories.Browser, Description = "Opens a custom modal with customized title, description and fields. On cancel / submit get triggered on user input.", Example = @"var userId = 1234UL; var modal = new JObject () { [ ""Title"" ] = ""My Title""; [ ""Description"" ] = $""This is my awesome description! Also, this is some content: {post [ ""Content"" ]}""; [ ""Fields"" ] = JObject.Parse ( JsonConvert.SerializeObject ( new Dictionary () { [ ""test"" ] = new JObject () { [ ""Title"" ] = ""Field #1"", [ ""IsRequired"" ] = true, [ ""DefaultValue"" ] = ""Potatoes suck!"" }, [ ""test1"" ] = new JObject () { [ ""Title"" ] = ""Field #2"", [ ""Description"" ] = ""To yeet or not to yeet."" }, } } ) ); RusterAddons?.Call ( ""OpenModal"", userId, modal, new Action> ( ( values ) => { Puts ( $""Test worked. {values[""test""]} and {values[""test1""]}"" ); } ), new Action ( () => { Puts ( $""Test cancelled."" ); } ) ); ", OverridenParameters = new string [] { "ulong", "JObject", "Action>", "Action" } )] [HookMethod ( nameof ( OpenModal ) )] public void OpenModal ( ulong userId, JObject modal, Action> onSubmit, Action onCancel ) { var browser = NET.GetBrowser ( userId ); browser.Modal = JsonConvert.DeserializeObject ( modal.ToString ( Formatting.None ) ); browser.Modal.ApplyDefaults (); browser.Modal.OnSubmit = () => { onSubmit?.Invoke ( browser.Modal.GetFieldValues () ); }; browser.Modal.OnCancel = onCancel; browser.DrawModal (); } [API ( Category = APIAttribute.Categories.Browser, Description = "Opens the color picker. On cancel / submit get triggered on user input.", Returns = "onColorPicked return the HEX and Unity color (0 0 0) in both of its parameters.", Example = @"RusterAddons?.Call ( ""OpenColorPicker"", userId, new Action ( ( hex, color ) => { Puts ( $""You've picked {hex}, aka {color}."" ); } ), new Action ( () => { Puts ( $""Cancelled color picker."" ); } ) ); // Output example: [RusterAddonsTest] You've picked D95C16FF, aka 0.85, 0.36125, 0.08750001.", OverridenParameters = new string [] { "ulong", "Action", "Action" } )] [HookMethod ( nameof ( OpenColorPicker ) )] public void OpenColorPicker ( ulong userId, Action onColorPicked, Action onCancel ) { var browser = NET.GetBrowser ( userId ); browser.DrawColorPicker ( onColorPicked: onColorPicked, onCancel: onCancel ); } #endregion #region Bot [API ( Category = APIAttribute.Categories.Bot, Description = "Creates a bot and uses the type value to install the bot commands. The bot gets uninstalled once the plugin's unloaded. Customize the bot using the CreateOrUpdateUser API call.", Example = @"public static class MyAwesomeBot { public static void CommandName1 ( int conversationId, ulong botId, string command, string [] arguments ) { Instance.Puts ( ""Command called!"" ); } public static string CommandName2 ( int conversationId, ulong botId, string command, string [] arguments ) { return $""Print this in chat. You called: {command}""; } } var botId = 12345UL; var prefix = '!'; var type = typeof ( MyAwesomeBot ); var plugin = this; [CALL] // Go to your DMs, have a custom group, add your bot in the group and call commandname1 or commandname2 in DM chat." )] [HookMethod ( nameof ( CreateBot ) )] public void CreateBot ( ulong botId, char prefix, Type type, Plugin plugin ) { NET.InstallBot ( botId, prefix, type, plugin ); } #endregion #endregion #region Hooks #region General [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user modifies their Ruster.NET language.", Returns = "User ID, pdated language and previous language." )] [HookMethod ( nameof ( RNETAPI_OnLanguageChange ) )] public void RNETAPI_OnLanguageChange ( ulong userId, string language, string previousLanguage ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnLanguageChange ) ), userId, language, previousLanguage ); [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user changes their nickname in Ruster.NET.", Returns = "User ID, older nickname and newer nickname." )] [HookMethod ( nameof ( RNETAPI_OnCustomNameChange ) )] public void RNETAPI_OnCustomNameChange ( ulong userId, string oldName, string newName ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnCustomNameChange ) ), userId, oldName, newName ); [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user withdrawed their wallet in Ruster.NET.", Returns = "User ID, amount withdrawn." )] [HookMethod ( nameof ( RNETAPI_OnWithdraw ) )] public void RNETAPI_OnWithdraw ( ulong userId, int amountWithdrawn ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnWithdraw ) ), userId, amountWithdrawn ); [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user restocks one or more posts.", Returns = "User ID, an array of posts that have been restocked." )] [HookMethod ( nameof ( RNETAPI_OnRestock ) )] public void RNETAPI_OnRestock ( ulong userId, RusterNET.RusterFeed.RusterPost [] postsRestocked ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnRestock ) ), userId, postsRestocked.Select ( x => ToParse ( x ) ).ToArray () ); [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user filters a feed.", Returns = "User ID, browser page (indicating the index of a feed in Ruster.NET) and hashtag." )] [HookMethod ( nameof ( RNETAPI_OnHashtagFilter ) )] public void RNETAPI_OnHashtagFilter ( ulong userId, int browserPage, RusterNET.RusterHashtag hashtag ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnHashtagFilter ) ), userId, browserPage, ToParse ( hashtag ) ); [Hook ( Category = HookAttribute.Categories.General, Description = "Called whenever an user cleared a feed hashtag filter.", Returns = "User ID and browser page (indicating the index of a feed in Ruster.NET)." )] [HookMethod ( nameof ( RNETAPI_OnHashtagFilterClear ) )] public void RNETAPI_OnHashtagFilterClear ( ulong userId, int browserPage ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnHashtagFilterClear ) ), userId, browserPage ); #endregion #region Post [Hook ( Category = HookAttribute.Categories.Post, Description = "Called when a new post has been created / published.", Returns = "The post and if it has been a silent publish or not." )] [HookMethod ( nameof ( RNETAPI_OnPostCreated ) )] public void RNETAPI_OnPostCreated ( RusterNET.RusterFeed.RusterPost post, bool silent ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostCreated ) ), ToParse ( post ), silent ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called when a post has been deleted / unpublished.", Returns = "The post and if it has been a silent deletion/unpublish or not." )] [HookMethod ( nameof ( RNETAPI_OnPostDeleted ) )] public void RNETAPI_OnPostDeleted ( RusterNET.RusterFeed.RusterPost post, bool silent ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostDeleted ) ), ToParse ( post ), silent ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called whenever a post has been opened by an user.", Returns = "User ID and the post." )] [HookMethod ( nameof ( RNETAPI_OnPostOpen ) )] public void RNETAPI_OnPostOpen ( ulong userId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostOpen ) ), userId, ToParse ( post ) ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called whenever a post has been closed by an user.", Returns = "User ID and the post." )] [HookMethod ( nameof ( RNETAPI_OnPostClose ) )] public void RNETAPI_OnPostClose ( ulong userId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostClose ) ), userId, ToParse ( post ) ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called whenever a post has been pinned.", Returns = "User ID and the pinned post." )] [HookMethod ( nameof ( RNETAPI_OnPostPinned ) )] public void RNETAPI_OnPostPinned ( ulong userId, ulong feedId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostPinned ) ), userId, feedId, ToParse ( post ) ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called whenever a post has been unpinned.", Returns = "User ID and the unpinned post." )] [HookMethod ( nameof ( RNETAPI_OnPostUnpinned ) )] public void RNETAPI_OnPostUnpinned ( ulong userId, ulong feedId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostUnpinned ) ), userId, feedId, ToParse ( post ) ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called when an user plays the audio-clip of a post.", Returns = "User ID, the post." )] [HookMethod ( nameof ( RNETAPI_OnPostPlay ) )] public void RNETAPI_OnPostPlay ( ulong userId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostCreated ) ), userId, ToParse ( post ) ); [Hook ( Category = HookAttribute.Categories.Post, Description = "Called when an user stops the audio-clip of a post.", Returns = "User ID, the post." )] [HookMethod ( nameof ( RNETAPI_OnPostStop ) )] public void RNETAPI_OnPostStop ( ulong userId, RusterNET.RusterFeed.RusterPost post ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnPostStop ) ), userId, ToParse ( post ) ); #endregion #region DM [Hook ( Category = HookAttribute.Categories.DM, Description = "Called when a direct message has been sent.", Returns = "The message." )] [HookMethod ( nameof ( RNETAPI_OnDMSent ) )] public void RNETAPI_OnDMSent ( int conversationId, RusterNET.RusterConversation.RusterDirectMessage message, bool silent ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnDMSent ) ), conversationId, ToParse ( message ), silent ); [Hook ( Category = HookAttribute.Categories.DM, Description = "Called when a direct message has been sent to a bot.", Returns = "The message." )] [HookMethod ( nameof ( RNETAPI_OnBotDMSent ) )] public void RNETAPI_OnBotDMSent ( int conversationId, RusterNET.RusterConversation.RusterDirectMessage message, bool silent ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnBotDMSent ) ), conversationId, ToParse ( message ), silent ); #endregion #region Browser [Hook ( Category = HookAttribute.Categories.Browser, Description = "Called when the browser opened." )] [HookMethod ( nameof ( RNETAPI_OnBrowserOpen ) )] public void RNETAPI_OnBrowserOpen ( ulong userId ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnBrowserOpen ) ), userId ); [Hook ( Category = HookAttribute.Categories.Browser, Description = "Called when the browser closed." )] [HookMethod ( nameof ( RNETAPI_OnBrowserClose ) )] public void RNETAPI_OnBrowserClose ( ulong userId ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnBrowserClose ) ), userId ); [Hook ( Category = HookAttribute.Categories.Browser, Description = "Called whenever an user added a new coupon to their account." )] [HookMethod ( nameof ( RNETAPI_OnCouponAdded ) )] public void RNETAPI_OnCouponAdded ( ulong userId, string coupon ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnCouponAdded ) ), userId, coupon ); [Hook ( Category = HookAttribute.Categories.Browser, Description = "Called whenever an user removed a coupon from their account." )] [HookMethod ( nameof ( RNETAPI_OnCouponRemoved ) )] public void RNETAPI_OnCouponRemoved ( ulong userId, string coupon ) => Interface.Oxide.CallHook ( GetHookName ( nameof ( RNETAPI_OnCouponRemoved ) ), userId, coupon ); #endregion #endregion #region Documentation public void GenerateDocumentation () { var hookMethods = typeof ( RusterAddons ).GetMethods ().Select ( x => new KeyValuePair ( x, x.GetCustomAttributes ( typeof ( HookAttribute ), true ) as HookAttribute [] ) ); var apiMethods = typeof ( RusterAddons ).GetMethods ().Select ( x => new KeyValuePair ( x, x.GetCustomAttributes ( typeof ( APIAttribute ), true ) as APIAttribute [] ) ); OsEx.File.Create ( $"RusterAddons_docs.html", Template ( hooks: Enum.GetNames ( typeof ( HookAttribute.Categories ) ).Select ( ( x ) => { var hooks = hookMethods.Where ( y => y.Value.Where ( z => Enum.GetName ( typeof ( HookAttribute.Categories ), z.Category ) == x ).Count () > 0 ); if ( hooks.Count () == 0 ) return string.Empty; return GetCategoryTemplate ( x, hooks.Select ( y => y.Value.Length == 0 ? "" : GetContentTemplate ( $"{y.Key.Name}-{y.Value.Length}_hook", ColorPallette.ContainsKey ( y.Key.ReturnType ) ? ColorPallette [ y.Key.ReturnType ] : "black", $"{GetHookTypeFormat ( y.Key.ReturnType )} {GetHookName ( y.Key.Name )} ( {y.Key.GetParameters ().Select ( z => $"{GetHookTypeFormat ( z.ParameterType )} {z.Name}" ).ToArray ().ToString ( ", ", ", " )} )", y.Value [ 0 ].Description, y.Value [ 0 ].Returns, $"{GetHookTypeFormat ( y.Key.ReturnType )} {GetHookName ( y.Key.Name )} ( {y.Key.GetParameters ().Select ( z => $"{GetAPITypeFormat ( z.ParameterType )} {z.Name}" ).ToArray ().ToString ( ", ", ", " )} )
{{

}}", null ) ).ToArray () ); } ).ToArray ().ToString ( "\n", "\n" ), api: Enum.GetNames ( typeof ( APIAttribute.Categories ) ).Select ( ( x ) => { var api = apiMethods.Where ( y => y.Value.Where ( z => Enum.GetName ( typeof ( APIAttribute.Categories ), z.Category ) == x ).Count () > 0 ); if ( api.Count () == 0 ) return string.Empty; return GetCategoryTemplate ( x, api.Select ( y => y.Value.Length == 0 ? "" : GetContentTemplate ( $"{y.Key.Name}-{y.Value.Length}", ColorPallette.ContainsKey ( y.Key.ReturnType ) ? ColorPallette [ y.Key.ReturnType ] : "black", $"{GetHookTypeFormat ( y.Key.ReturnType )} {GetHookName ( y.Key.Name )} ( {y.Key.GetParameters ().Select ( z => $"{GetProperAPITypeFormat ( z.ParameterType, y.Value [ 0 ], y.Key.GetParameters () )} {z.Name}" ).ToArray ().ToString ( ", ", ", " )} )", y.Value [ 0 ].Description, y.Value [ 0 ].Returns, $@"RusterAddons.Call{( y.Key.ReturnType == typeof ( void ) ? "" : $"<{GetHookTypeFormat ( y.Key.ReturnType )}>" )} ( ""{GetHookName ( y.Key.Name )}""{( y.Key.GetParameters ().Length > 0 ? $", {y.Key.GetParameters ().Select ( z => $"{z.Name}" ).ToArray ().ToString ( ", ", ", " )} )" : " )" )};", string.IsNullOrEmpty ( y.Value [ 0 ].Example ) ? "" : $"{y.Value [ 0 ].Example}".Replace ( "[CALL]", $"{( y.Key.ReturnType == typeof ( void ) ? "" : "var call = " )}" + $@"RusterAddons.Call{( y.Key.ReturnType == typeof ( void ) ? "" : $"<{GetHookTypeFormat ( y.Key.ReturnType )}>" )} ( ""{GetHookName ( y.Key.Name )}""{( y.Key.GetParameters ().Length > 0 ? $", {y.Key.GetParameters ().Select ( z => $"{z.Name}" ).ToArray ().ToString ( ", ", ", " )} )" : " )" )};" ) ) ).ToArray () ); } ).ToArray ().ToString ( "\n", "\n" ), types: Types.Select ( x => GetContentTemplate ( $"{x.Name}_api", "black", x.Name, $"JSON structure of {x.Name}.", null, JsonConvert.SerializeObject ( Activator.CreateInstance ( x ), Formatting.Indented ), TypeExamples.ContainsKey ( x ) ? TypeExamples [ x ] : null ) ).ToArray ().ToString ( "\n", "\n" ) ) ); } public Dictionary ColorPallette { get; } = new Dictionary () { [ typeof ( ulong ) ] = "#f5b942", [ typeof ( int ) ] = "#f55d42", [ typeof ( string ) ] = "#b6f542", [ typeof ( bool ) ] = "#42f5e9", [ typeof ( ulong [] ) ] = "#427bf5", [ typeof ( int [] ) ] = "#8d42f5", [ typeof ( JObject ) ] = "#f542aa", [ typeof ( JObject [] ) ] = "#c42b78", [ typeof ( void ) ] = "#f54242" }; public Type [] Types { get; } = new Type [] { typeof ( RusterNET.RusterFeed ), typeof ( RusterNET.RusterFeed.RusterPost ), typeof ( RusterNET.RusterMarketplaceListing ), typeof ( RusterNET.RusterStory ), typeof ( RusterNET.RusterCoupon ), typeof ( RusterNET.RusterTransaction ), typeof ( RusterNET.RusterUser ), typeof ( RusterNET.RusterGif ), typeof ( RusterNET.RusterFlipbook ), typeof ( RusterNET.RusterModal ), typeof ( RusterNET.RusterModal.RusterField), typeof ( RusterNET.RusterLicensedItem ), typeof ( RusterNET.RusterGiftCard ), typeof ( RusterNET.RusterUserConfiguration ), typeof ( RusterNET.RusterUserNotification ), typeof ( RusterNET.RusterConversation ), typeof ( RusterNET.RusterConversation.RusterDirectMessage ), typeof ( RusterNET.RusterEmoji ), typeof ( RusterNET.RusterFriendRequest ), typeof ( RusterNET.RusterHashtag ), typeof ( RusterNET.RusterBusinessCard), typeof ( RusterNET.RusterBot ), typeof ( RusterNET.RusterBot.Command ), }; public Dictionary TypeExamples { get; } = new Dictionary { [ typeof ( RusterNET.RusterModal ) ] = JsonConvert.SerializeObject ( new RusterNET.RusterModal { Title = "Report", Description = "Report this player for something that's unholy.", Fields = new Dictionary { [ "field01" ] = new RusterNET.RusterModal.RusterField { Title = "My Field #01", Description = "My not-mandatory description.", IsRequired = true, FieldType = RusterNET.RusterModal.RusterField.FieldTypes.Toggle }, [ "field02" ] = new RusterNET.RusterModal.RusterField { Title = "My Field #02", IsRequired = false, FieldType = RusterNET.RusterModal.RusterField.FieldTypes.String } } }, Formatting.Indented ) }; [AttributeUsage ( AttributeTargets.Method )] public class HookAttribute : Attribute { public Categories Category { get; set; } = Categories.None; public string Description { get; set; } public string Returns { get; set; } public string Example { get; set; } public enum Categories { None, Browser, General, User, Bot, Post, Feed, DM, } } [AttributeUsage ( AttributeTargets.Method )] public class APIAttribute : Attribute { public Categories Category { get; set; } = Categories.None; public string Description { get; set; } public string Returns { get; set; } public string Example { get; set; } public string [] OverridenParameters { get; set; } public enum Categories { None, Browser, General, User, Bot, Post, Feed, DM } } public string GetHookTypeFormat ( Type type ) { switch ( type.Name ) { case "UInt64": return "ulong"; case "UInt64[]": return "ulong[]"; case "Int32": case "Single": return "int"; case "Int32[]": return "int[]"; case "Boolean": return "bool"; case "String": return "string"; case "JObject": return "JObject"; case "Void": return "void"; } return type.Name; } public string GetAPITypeFormat ( Type type ) { switch ( type.Name ) { case "UInt64": return "ulong"; case "UInt64[]": return "ulong[]"; case "Int32": case "Single": return "int"; case "Int32[]": return "int[]"; case "Boolean": return "bool"; case "String": return "string"; case "Void": return "void"; case "Type": return "Type"; case "Plugin": return "Plugin"; case "Char": return "char"; default: return $"JObject{( type.IsArray ? "[]" : "" )}"; } } public string GetProperAPITypeFormat ( Type type, APIAttribute api, System.Reflection.ParameterInfo [] parameters ) { if ( api.OverridenParameters == null || api.OverridenParameters.Length == 0 ) return GetAPITypeFormat ( type ); for ( int i = 0; i < parameters.Length; i++ ) { if ( i > api.OverridenParameters.Length - 1 ) return GetAPITypeFormat ( type ); if ( parameters [ i ].ParameterType == type ) return api.OverridenParameters [ i ].Replace ( "<", "<" ).Replace ( ">", ">" ); } return GetAPITypeFormat ( type ); } public string Template ( string hooks, string api, string types ) { return @" Ruster.NET Addons v" + Version + @" Documentation

Ruster.NET Addons v" + Version + @"

Hooks & API for Ruster.NET v" + NET.Version + @"

API

" + api + @"

Hooks

" + hooks + @"

Types

" + types + @"
"; } public string GetCategoryTemplate ( string title, string [] content ) { return $@"
{title}
{content.ToString ( "\n", "\n" )}
"; } public string GetContentTemplate ( string id, string color, string title, string subtitle, string returns, string template, string example ) { return $@"
{title}
{subtitle}

{( string.IsNullOrEmpty ( template ) ? "" : $"Template:\n
{template}
" )} {( string.IsNullOrEmpty ( returns ) ? "" : $"Returns: {returns}
" )} {( string.IsNullOrEmpty ( example ) ? "" : $"{( string.IsNullOrEmpty ( returns ) ? "" : "
" )}Example:\n
{example.Replace ( "<", "<" ).Replace ( ">", ">" )}
" )}
"; } #endregion } }