diff --git a/.gitignore b/.gitignore
index 940794e..5cce309 100644
--- a/.gitignore
+++ b/.gitignore
@@ -286,3 +286,5 @@ __pycache__/
*.btm.cs
*.odx.cs
*.xsd.cs
+
+push.bat
\ No newline at end of file
diff --git a/VRChatApi/TestClient/App.config b/VRChatApi/TestClient/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/VRChatApi/TestClient/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VRChatApi/TestClient/Properties/AssemblyInfo.cs b/VRChatApi/TestClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d753e44
--- /dev/null
+++ b/VRChatApi/TestClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestClient")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("51e73a81-edc2-4790-90ca-38de49ff20c9")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/VRChatApi/VRChatApi.Tests/VRChatApi.Tests.csproj b/VRChatApi/VRChatApi.Tests/VRChatApi.Tests.csproj
index 81e3ad1..153a2b4 100644
--- a/VRChatApi/VRChatApi.Tests/VRChatApi.Tests.csproj
+++ b/VRChatApi/VRChatApi.Tests/VRChatApi.Tests.csproj
@@ -11,11 +11,11 @@
-
-
-
-
-
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/VRChatApi/VRChatApi/Classes/AvatarResponse.cs b/VRChatApi/VRChatApi/Classes/AvatarResponse.cs
index 614958d..74d5f7c 100644
--- a/VRChatApi/VRChatApi/Classes/AvatarResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/AvatarResponse.cs
@@ -1,12 +1,33 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class AvatarResponse
+ public class AssetUrlObject
+ {
+ }
+
+ public class UnityPackage
+ {
+ public string id { get; set; }
+ public string assetUrl { get; set; }
+ public AssetUrlObject assetUrlObject { get; set; }
+ public string unityVersion { get; set; }
+ public long unitySortNumber { get; set; }
+ public int assetVersion { get; set; }
+ public string platform { get; set; }
+ public DateTime created_at { get; set; }
+ }
+
+ public class UnityPackageUrlObject
+ {
+ public string unityPackageUrl { get; set; }
+ }
+
+ public class AvatarResponse : Response
{
public string id { get; set; }
public string name { get; set; }
@@ -15,6 +36,7 @@ public class AvatarResponse
public string authorName { get; set; }
public List tags { get; set; }
public string assetUrl { get; set; }
+ public AssetUrlObject assetUrlObject { get; set; }
public string imageUrl { get; set; }
public string thumbnailImageUrl { get; set; }
public string releaseStatus { get; set; }
@@ -23,6 +45,8 @@ public class AvatarResponse
public List unityPackages { get; set; }
public bool unityPackageUpdated { get; set; }
public string unityPackageUrl { get; set; }
-
+ public UnityPackageUrlObject unityPackageUrlObject { get; set; }
+ public DateTime created_at { get; set; }
+ public DateTime updated_at { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/ConfigResponse.cs b/VRChatApi/VRChatApi/Classes/ConfigResponse.cs
index 6442a0e..bc6c3c1 100644
--- a/VRChatApi/VRChatApi/Classes/ConfigResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/ConfigResponse.cs
@@ -1,8 +1,28 @@
-using System.Collections.Generic;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class ConfigResponse
+ public class DynamicWorldRow
+ {
+ public string name { get; set; }
+ public string sortHeading { get; set; }
+ public string sortOwnership { get; set; }
+ public string sortOrder { get; set; }
+ public string platform { get; set; }
+ public int index { get; set; }
+ public string tag { get; set; }
+ }
+
+ public class Announcement
+ {
+ public string name { get; set; }
+ public string text { get; set; }
+ }
+
+ public class ConfigResponse : Response
{
public string messageOfTheDay { get; set; }
public string timeOutWorldId { get; set; }
@@ -11,6 +31,7 @@ public class ConfigResponse
public string downloadLinkWindows { get; set; }
public string releaseAppVersionStandalone { get; set; }
public string devAppVersionStandalone { get; set; }
+ public string devServerVersionStandalone { get; set; }
public string devDownloadLinkWindows { get; set; }
public int currentTOSVersion { get; set; }
public string releaseSdkUrl { get; set; }
@@ -26,14 +47,36 @@ public class ConfigResponse
public string tutorialWorldId { get; set; }
public bool disableEventStream { get; set; }
public bool disableAvatarGating { get; set; }
- public List registrationShitList { get; set; }
+ public bool disableFeedbackGating { get; set; }
+ public bool disableRegistration { get; set; }
+ public bool disableUpgradeAccount { get; set; }
+ public bool disableCommunityLabs { get; set; }
+ public bool disableCommunityLabsPromotion { get; set; }
+ public bool disableTwoFactorAuth { get; set; }
+ public bool disableSteamNetworking { get; set; }
public string plugin { get; set; }
+ public string sdkNotAllowedToPublishMessage { get; set; }
+ public string sdkDeveloperFaqUrl { get; set; }
+ public string sdkDiscordUrl { get; set; }
+ public string notAllowedToSelectAvatarInPrivateWorldMessage { get; set; }
+ public int userVerificationTimeout { get; set; }
+ public int userUpdatePeriod { get; set; }
+ public int userVerificationDelay { get; set; }
+ public int userVerificationRetry { get; set; }
+ public int worldUpdatePeriod { get; set; }
+ public int moderationQueryPeriod { get; set; }
+ public int clientDisconnectTimeout { get; set; }
+ public string defaultAvatar { get; set; }
+ public List dynamicWorldRows { get; set; }
+ public bool disableAvatarCopying { get; set; }
+ public List announcements { get; set; }
public string address { get; set; }
public string contactEmail { get; set; }
public string supportEmail { get; set; }
public string jobsEmail { get; set; }
public string copyrightEmail { get; set; }
public string moderationEmail { get; set; }
+ public bool disableEmail { get; set; }
public string appName { get; set; }
public string serverName { get; set; }
public string deploymentGroup { get; set; }
diff --git a/VRChatApi/VRChatApi/Classes/FavoritesResponse.cs b/VRChatApi/VRChatApi/Classes/FavoritesResponse.cs
new file mode 100644
index 0000000..fc60fe5
--- /dev/null
+++ b/VRChatApi/VRChatApi/Classes/FavoritesResponse.cs
@@ -0,0 +1,21 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VRChatApi.Classes
+{
+ public class FavoritesResponse : Response
+ {
+ public string id { get; set; }
+ public string type { get; set; }
+ public string favoriteId { get; set; }
+ public string[] tags { get; set; }
+ }
+ public enum FavoriteType
+ {
+
+ }
+}
diff --git a/VRChatApi/VRChatApi/Classes/FavouriteResponse.cs b/VRChatApi/VRChatApi/Classes/FavouriteResponse.cs
new file mode 100644
index 0000000..295ca37
--- /dev/null
+++ b/VRChatApi/VRChatApi/Classes/FavouriteResponse.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+#pragma warning disable IDE1006
+
+namespace VRChatApi.Classes
+{
+ public class FavouriteResponse : Response
+ {
+ public string id { get; set; }
+ public string type { get; set; }
+ public string favoriteId { get; set; }
+ public List tags { get; set; }
+ }
+}
diff --git a/VRChatApi/VRChatApi/Classes/NotificationResponse.cs b/VRChatApi/VRChatApi/Classes/NotificationResponse.cs
index a4595a6..68014a4 100644
--- a/VRChatApi/VRChatApi/Classes/NotificationResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/NotificationResponse.cs
@@ -1,23 +1,38 @@
-using System;
-using System.ComponentModel;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class NotificationResponse
+ public class NotificationDetails
{
- public string id { get; set; }
- public string type { get; set; }
- public string senderUserId { get; set; }
- public string receiverUserId { get; set; }
- public string message { get; set; }
- public JObject details { get; set; } // unknown
- public string jobName { get; set; }
- public string jobColor { get; set; }
-
- [Obsolete("Typoed property, use receiverUserId instead")]
+ public string WorldId { get; set; }
[JsonIgnore]
- public string recieverUserId { get => receiverUserId; set => receiverUserId = value; }
+ public bool rsvp { get; set; }
+ public string WorldName { get; set; }
+ }
+
+ public class NotificationResponse : Response
+ {
+ public string Id { get; set; }
+ public string Type { get; set; }
+ public string SenderUserId { get; set; }
+ public string SenderUsername { get; set; }
+ public string ReceiverUserId { get; set; }
+ public string Message { get; set; }
+ [JsonProperty(PropertyName = "created_at")]
+ public string Created { get; set; }
+ public DateTime CreatedAt { get { return Convert.ToDateTime(Created); } }
+ public string JobName { get; set; }
+ public string JobColor { get; set; }
+ }
+ public class NotificationResponseWithDetails : NotificationResponse
+ {
+ public NotificationDetails Details { get; set; }
+ }
+ public class NotificationResponseWithSeen : NotificationResponse
+ {
+ public bool Seen { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/PlayerModeratedResponse.cs b/VRChatApi/VRChatApi/Classes/PlayerModeratedResponse.cs
index fce2883..e4e3201 100644
--- a/VRChatApi/VRChatApi/Classes/PlayerModeratedResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/PlayerModeratedResponse.cs
@@ -4,9 +4,11 @@
using System.Text;
using System.Threading.Tasks;
+#pragma warning disable IDE1006
+
namespace VRChatApi.Classes
{
- public class PlayerModeratedResponse
+ public class PlayerModeratedResponse : Response
{
public string id { get; set; }
public string type { get; set; }
@@ -14,6 +16,6 @@ public class PlayerModeratedResponse
public string sourceDisplayName { get; set; }
public string targetUserId { get; set; }
public string targetDisplayName { get; set; }
- public string created { get; set; }
+ public DateTime created { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/Response.cs b/VRChatApi/VRChatApi/Classes/Response.cs
new file mode 100644
index 0000000..fce3082
--- /dev/null
+++ b/VRChatApi/VRChatApi/Classes/Response.cs
@@ -0,0 +1,59 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VRChatApi.Classes
+{
+ public class Response
+ {
+
+ [JsonIgnore]
+ public HttpResponseMessage Raw { get; set; }
+ /*public object Content { get; set; }
+ public object Status { get; set; }
+ public async Task FromResponseMessageAsync(HttpResponseMessage response) { // , object content = null
+ // if (content != null) Content = content;
+ if (response != null) {
+ Raw = response;
+ string json = await response.Content.ReadAsStringAsync();
+ try { Status = JsonConvert.DeserializeObject(json);
+ } catch { Status = JsonConvert.DeserializeObject(json); }
+ }
+ return this;
+ }*/
+ }
+ public class Message
+ {
+ [JsonProperty(PropertyName = "message")]
+ public string _message { get; set; }
+ [JsonIgnore]
+ public string Content { get { return _message; } }
+ public int status_code { get; set; }
+ [JsonIgnore]
+ public System.Net.HttpStatusCode StatusCode { get { return (System.Net.HttpStatusCode)status_code; } }
+ }
+
+ public class Success
+ {
+ public Message success { get; set; }
+ }
+ public class Error
+ {
+ public Message error { get; set; }
+ }
+ public class BanResponse : Error
+ {
+ [JsonIgnore]
+ public bool Banned { get { return (ExpiresAt < DateTime.Now) ? true : false; } }
+ public string Target { get; set; }
+ public string Reason { get; set; }
+ public string Expires { get; set; }
+ [JsonIgnore]
+ public DateTime ExpiresAt { get { return Convert.ToDateTime(Expires); } }
+ [JsonIgnore]
+ public TimeSpan ExpiresIn { get { return ExpiresAt - DateTime.Now; } }
+ }
+}
diff --git a/VRChatApi/VRChatApi/Classes/UserBriefResponse.cs b/VRChatApi/VRChatApi/Classes/UserBriefResponse.cs
index fc12710..4dc0498 100644
--- a/VRChatApi/VRChatApi/Classes/UserBriefResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/UserBriefResponse.cs
@@ -1,20 +1,60 @@
using System.Collections.Generic;
+using Newtonsoft.Json;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class UserBriefResponse
+ public class UserStatus
+ {
+ public enum Status
+ {
+ Unknown, Offline, Busy, Active, JoinMe
+ }
+ public Status FromString(string status)
+ {
+ switch (status.ToLowerInvariant())
+ {
+ case "join me":
+ return Status.JoinMe;
+ case "active":
+ return Status.Active;
+ case "busy":
+ return Status.Busy;
+ case "offline":
+ return Status.Offline;
+ default:
+ return Status.Unknown;
+ }
+ }
+ public string ToString(Status status)
+ {
+ switch (status)
+ {
+ case Status.Offline: return "offline";
+ case Status.Busy: return "busy";
+ case Status.Active: return "active";
+ case Status.JoinMe: return "join me";
+ default: return "";
+ }
+ }
+ }
+ public class UserBriefResponse : Response
{
+ [JsonIgnore]
+ public bool Offline { get; set; }
public string id { get; set; }
public string username { get; set; }
public string displayName { get; set; }
public string currentAvatarImageUrl { get; set; }
public string currentAvatarThumbnailImageUrl { get; set; }
- public string developerType { get; set; }
+ public string last_platform { get; set; }
public List tags { get; set; }
+ public string developerType { get; set; }
public string status { get; set; }
public string statusDescription { get; set; }
+ public string friendKey { get; set; }
+ public bool isFriend { get; set; }
public string location { get; set; }
- public string worldId { get; set; }
- public string instanceId { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/UserResponse.cs b/VRChatApi/VRChatApi/Classes/UserResponse.cs
index c92cb78..c16cc55 100644
--- a/VRChatApi/VRChatApi/Classes/UserResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/UserResponse.cs
@@ -1,31 +1,52 @@
-using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
+#pragma warning disable IDE1006
+
namespace VRChatApi.Classes
{
public class PastDisplayName
{
- string displayName { get; set; }
- string updated_at { get; set; }
+ public string displayName { get; set; }
+ public DateTime updated_at { get; set; }
+ }
+
+ public class SteamDetails
+ {
+ }
+
+ public class Feature
+ {
+ public bool twoFactorAuth { get; set; }
}
public class UserResponse : UserBriefResponse
{
public List pastDisplayNames { get; set; }
public bool hasEmail { get; set; }
+ public bool hasPendingEmail { get; set; }
public string obfuscatedEmail { get; set; }
+ public string obfuscatedPendingEmail { get; set; }
public bool emailVerified { get; set; }
public bool hasBirthday { get; set; }
public bool unsubscribe { get; set; }
public List friends { get; set; }
- public JObject blueprints { get; set; }
- public JObject currentAvatarBlueprint { get; set; }
- public List events { get; set; }
+ public List friendGroupNames { get; set; }
public string currentAvatar { get; set; }
public string currentAvatarAssetUrl { get; set; }
public int acceptedTOSVersion { get; set; }
- public JObject steamDetails { get; set; }
+ public string steamId { get; set; }
+ public SteamDetails steamDetails { get; set; }
+ public string oculusId { get; set; }
public bool hasLoggedInFromClient { get; set; }
- public string authToken { get; set; }
+ public string homeLocation { get; set; }
+ public bool twoFactorAuthEnabled { get; set; }
+ public Feature feature { get; set; }
+ public string state { get; set; }
+ public DateTime last_login { get; set; }
+ public bool allowAvatarCopying { get; set; }
+ public List onlineFriends { get; set; }
+ public List activeFriends { get; set; }
+ public List offlineFriends { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/WorldBriefResponse.cs b/VRChatApi/VRChatApi/Classes/WorldBriefResponse.cs
index 8aa9154..eed6244 100644
--- a/VRChatApi/VRChatApi/Classes/WorldBriefResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldBriefResponse.cs
@@ -1,27 +1,36 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
+#pragma warning disable IDE1006
+
namespace VRChatApi.Classes
{
- public class WorldBriefResponse
+ public class WorldBriefResponse : Response
{
public string id { get; set; }
public string name { get; set; }
+ public string authorId { get; set; }
public string authorName { get; set; }
- public int totalLikes { get; set; }
- public int totalVisits { get; set; }
+ public int capacity { get; set; }
public string imageUrl { get; set; }
public string thumbnailImageUrl { get; set; }
- public bool isSecure { get; set; } // Unknown
+
[JsonConverter(typeof(StringEnumConverter))]
public ReleaseStatus releaseStatus { get; set; }
- public string organization { get; set; } // Unknown
+
+ public string organization { get; set; }
+ public List tags { get; set; }
+ public int favorites { get; set; }
+ public DateTime created_at { get; set; }
+ public DateTime updated_at { get; set; }
+ public DateTime publicationDate { get; set; }
+ public DateTime labsPublicationDate { get; set; }
+ public int visits { get; set; }
+ public List unityPackages { get; set; }
+ public int popularity { get; set; }
+ public int heat { get; set; }
public int occupants { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/WorldEnums.cs b/VRChatApi/VRChatApi/Classes/WorldEnums.cs
index 52bf753..89cde54 100644
--- a/VRChatApi/VRChatApi/Classes/WorldEnums.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldEnums.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
namespace VRChatApi.Classes
{
@@ -22,9 +18,13 @@ public enum SortOptions
public enum ReleaseStatus
{
+ [Description("public")]
Public,
+ [Description("private")]
Private,
+ [Description("all")]
All,
+ [Description("hidden")]
Hidden,
}
diff --git a/VRChatApi/VRChatApi/Classes/WorldInstanceResponse.cs b/VRChatApi/VRChatApi/Classes/WorldInstanceResponse.cs
index af9f576..346b351 100644
--- a/VRChatApi/VRChatApi/Classes/WorldInstanceResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldInstanceResponse.cs
@@ -1,14 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class WorldInstanceResponse
+ public class WorldInstanceResponse : Response
{
public string id { get; set; }
public string name { get; set; }
diff --git a/VRChatApi/VRChatApi/Classes/WorldInstanceUserResponse.cs b/VRChatApi/VRChatApi/Classes/WorldInstanceUserResponse.cs
index bf0b33b..06fa857 100644
--- a/VRChatApi/VRChatApi/Classes/WorldInstanceUserResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldInstanceUserResponse.cs
@@ -8,7 +8,7 @@
namespace VRChatApi.Classes
{
- public class WorldInstanceUserResponse
+ public class WorldInstanceUserResponse : Response
{
public string id { get; set; }
public string username { get; set; }
diff --git a/VRChatApi/VRChatApi/Classes/WorldMetadataResponse.cs b/VRChatApi/VRChatApi/Classes/WorldMetadataResponse.cs
index d343781..db60303 100644
--- a/VRChatApi/VRChatApi/Classes/WorldMetadataResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldMetadataResponse.cs
@@ -1,15 +1,85 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Newtonsoft.Json.Linq;
+
+#pragma warning disable IDE1006
namespace VRChatApi.Classes
{
- public class WorldMetadataResponse
+ public class EventPortal
+ {
+ public string eventName { get; set; }
+ public string worldId { get; set; }
+ public DateTime eventStartTimeUtc { get; set; }
+ public string eventDuration { get; set; }
+ }
+
+ public class Metadata
+ {
+ public string CENTER_TEXT { get; set; }
+ public string CENTER_TEXT2 { get; set; }
+ public List PANOS { get; set; }
+ public List AVATAR_CUSTOM { get; set; }
+ public List AVATAR_FEATURED { get; set; }
+ public List AVATAR_HELP { get; set; }
+ public List AVATAR_MORPH { get; set; }
+ public List AVATAR_PEDESTAL { get; set; }
+ public List EVENTHALL_WELCOME { get; set; }
+ public List EVENTHAPPENING { get; set; }
+ public List EVENTS { get; set; }
+ public List MICROPHONE { get; set; }
+ public List PANOSPHERE { get; set; }
+ public List TIPS { get; set; }
+ public List WELCOME { get; set; }
+ public List WELCOME_2 { get; set; }
+ public List WORLD_CREATION { get; set; }
+ public List WORLD_FEATURED_ONE { get; set; }
+ public List WORLD_FEATURED_THREE { get; set; }
+ public List WORLD_FEATURED_TWO { get; set; }
+ public List WORLD_HELP { get; set; }
+ public List HELP_ROOM_1 { get; set; }
+ public List HELP_ROOM_2 { get; set; }
+ public List HELP_ROOM_3 { get; set; }
+ public List HELP_ROOM_4 { get; set; }
+ public List STAFF_PORTAL_1 { get; set; }
+ public string STAFF_CREATOR_1 { get; set; }
+ public List STAFF_IMAGE_1 { get; set; }
+ public List STAFF_PORTAL_2 { get; set; }
+ public string STAFF_CREATOR_2 { get; set; }
+ public List STAFF_IMAGE_2 { get; set; }
+ public List STAFF_PORTAL_3 { get; set; }
+ public string STAFF_CREATOR_3 { get; set; }
+ public List STAFF_IMAGE_3 { get; set; }
+ public string AVATAR_1 { get; set; }
+ public string AVATAR_2 { get; set; }
+ public string AVATAR_3 { get; set; }
+ public List EVENT_CALENDAR { get; set; }
+ public List LOCATION_SPAWN { get; set; }
+ public List HELP_WELCOME { get; set; }
+ public List AVATAR_WELCOME { get; set; }
+ public List NEW_WORLDS_WELCOME { get; set; }
+ public List FEATURED_WORLDS_WELCOME { get; set; }
+ public List EVENTHALL_MARQUEE { get; set; }
+ public List FOUNTAIN_WELCOME { get; set; }
+ public List EVENT_PORTAL { get; set; }
+ public List HELP_PORTAL_1 { get; set; }
+ public List HELP_PORTAL_2 { get; set; }
+ public bool NameplatesVisibleByDefault { get; set; }
+ public List HELP_PORTALS { get; set; }
+ public List EVENT_PORTAL_1 { get; set; }
+ public List EVENT_PORTAL_2 { get; set; }
+ public List EVENT_PORTAL_3 { get; set; }
+ public List EVENT_PORTAL_4 { get; set; }
+ public List AVATAR_PORTAL_1 { get; set; }
+ public List AVATAR_PORTAL_2 { get; set; }
+ public List AVATAR_STATIC_PORTAL_1 { get; set; }
+ public List AVATAR_STATIC_PORTAL_2 { get; set; }
+ public List FIREPIT_PORTAL_2 { get; set; }
+ public List FIREPIT_PORTAL_1 { get; set; }
+ }
+
+ public class WorldMetadataResponse : Response
{
public string id { get; set; }
- public JObject metadata { get; set; }
+ public Metadata metadata { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Classes/WorldResponse.cs b/VRChatApi/VRChatApi/Classes/WorldResponse.cs
index e3ae0d6..61e52a7 100644
--- a/VRChatApi/VRChatApi/Classes/WorldResponse.cs
+++ b/VRChatApi/VRChatApi/Classes/WorldResponse.cs
@@ -1,64 +1,36 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
+#pragma warning disable IDE1006
+
namespace VRChatApi.Classes
{
- public class UnityPackage
- {
- public string id { get; set; }
- public string assetUrl { get; set; }
- public string pluginUrl { get; set; }
- public string unityVersion { get; set; }
- public int unitySortNumber { get; set; }
- public int assetVersion { get; set; }
- public string platform { get; set; }
- [JsonProperty(PropertyName = "created_at")]
- public string createdTime { get; set; }
- }
-
public class WorldInstance
{
public string id { get; set; }
public int occupants { get; set; }
}
- public class WorldResponse
+ public class WorldResponse : WorldBriefResponse
{
- public string id { get; set; }
- public string name { get; set; }
public string description { get; set; }
public bool featured { get; set; }
- public string authorId { get; set; }
- public string authorName { get; set; }
public int totalLikes { get; set; }
public int totalVisits { get; set; }
- public short capacity { get; set; }
- public List tags { get; set; }
- [JsonConverter(typeof(StringEnumConverter))]
- public ReleaseStatus releaseStatus { get; set; }
- public string imageUrl { get; set; }
- public string thumbnailImageUrl { get; set; }
public string assetUrl { get; set; }
public string pluginUrl { get; set; }
public string unityPackageUrl { get; set; }
[JsonProperty(PropertyName = "namespace")]
public string nameSpace { get; set; } // Unknown
public bool unityPackageUpdated { get; set; } // Unknown
- public List unityPackages { get; set; }
public bool isSecure { get; set; } // Unknown
public bool isLockdown { get; set; } // Unknown
public int version { get; set; }
- public string organization { get; set; } // Unknown
[JsonProperty(PropertyName = "instances")]
public List _instances { get; set; }
[JsonIgnore]
public List instances { get; set; }
- public int occupants { get; set; }
}
}
diff --git a/VRChatApi/VRChatApi/Endpoints/AvatarApi.cs b/VRChatApi/VRChatApi/Endpoints/AvatarApi.cs
index 820c4fe..99f24dc 100644
--- a/VRChatApi/VRChatApi/Endpoints/AvatarApi.cs
+++ b/VRChatApi/VRChatApi/Endpoints/AvatarApi.cs
@@ -1,10 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
-using Newtonsoft.Json;
using VRChatApi.Classes;
using VRChatApi.Logging;
@@ -17,19 +14,25 @@ public class AvatarApi
public async Task GetById(string id)
{
Logger.Debug(() => $"Getting avatar details using ID: {id}");
- HttpResponseMessage response = await Global.HttpClient.GetAsync($"avatars/{id}?apiKey={Global.ApiKey}");
- AvatarResponse res = null;
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"avatars/{id}?apiKey={Global.ApiKey}");
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
+ return await Utils.ParseResponse(response);
+ }
+ public async Task> Personal(ReleaseStatus releaseStatus = ReleaseStatus.All, int amount = 100) => await List(releaseStatus: releaseStatus, amount: amount, user: "me");
- res = JsonConvert.DeserializeObject(json);
- }
+ public async Task> List(ReleaseStatus releaseStatus = ReleaseStatus.All, int amount = 100, string user = null)
+ {
+ var sb = new StringBuilder();
+ if (!string.IsNullOrEmpty(user)) sb.Append($"&user={user}");
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"avatars?apiKey={Global.ApiKey}&releaseStatus={releaseStatus.GetDescription()}&n={amount}{sb.ToString()}");
+ return await Utils.ParseResponse>(response);
+ }
- return res;
+ public async Task> Favorites(int amount = 16)
+ {
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"avatars/favorites?apiKey={Global.ApiKey}&n={amount}");
+ return await Utils.ParseResponse>(response);
}
}
}
diff --git a/VRChatApi/VRChatApi/Endpoints/FavoritesAPI.cs b/VRChatApi/VRChatApi/Endpoints/FavoritesAPI.cs
new file mode 100644
index 0000000..f0a84c2
--- /dev/null
+++ b/VRChatApi/VRChatApi/Endpoints/FavoritesAPI.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using VRChatApi.Classes;
+using VRChatApi.Logging;
+
+namespace VRChatApi.Endpoints
+{
+ public class FavoritesAPI
+ {
+ private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();
+ public async Task> Get(string type = null)
+ {
+ bool hasType = (type != null);
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"favorites?apiKey={Global.ApiKey}{(hasType ? $"&type={type}":"")}");
+ List res = null;
+ if (response.IsSuccessStatusCode)
+ {
+ var json = await response.Content.ReadAsStringAsync();
+ Logger.Debug(() => $"JSON received: {json}");
+
+ res = JsonConvert.DeserializeObject>(json);
+ }
+
+ return res;
+ }
+ }
+}
diff --git a/VRChatApi/VRChatApi/Endpoints/FavouriteApi.cs b/VRChatApi/VRChatApi/Endpoints/FavouriteApi.cs
new file mode 100644
index 0000000..a347ab2
--- /dev/null
+++ b/VRChatApi/VRChatApi/Endpoints/FavouriteApi.cs
@@ -0,0 +1,46 @@
+using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using VRChatApi.Classes;
+
+namespace VRChatApi.Endpoints
+{
+ public class FavouriteApi
+ {
+
+ public async Task FavouriteAvatar(string avatarId)
+ {
+ JObject json = new JObject()
+ {
+ { "type", "avatar" },
+ { "favoriteId", avatarId },
+ { "tags", new JArray(new[] { "avatars1" })}
+ };
+
+ StringContent content = new StringContent(json.ToString(), Encoding.UTF8);
+
+ content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+
+ HttpResponseMessage response = await Global.HttpClient.PostAsync($"favorites?apiKey={Global.ApiKey}", content);
+
+ return await Utils.ParseResponse(response);
+ }
+
+ public async Task> GetFavourites(string favouriteType = "avatar")
+ {
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"favorites?type={favouriteType}&apiKey={Global.ApiKey}");
+
+ return await Utils.ParseResponse>(response);
+ }
+
+ public async Task GetFavourite(string favouriteId)
+ {
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"favorites/{favouriteId}?apiKey={Global.ApiKey}");
+
+ return await Utils.ParseResponse(response);
+ }
+ }
+}
diff --git a/VRChatApi/VRChatApi/Endpoints/FriendsApi.cs b/VRChatApi/VRChatApi/Endpoints/FriendsApi.cs
index d81eed7..2766304 100644
--- a/VRChatApi/VRChatApi/Endpoints/FriendsApi.cs
+++ b/VRChatApi/VRChatApi/Endpoints/FriendsApi.cs
@@ -4,7 +4,6 @@
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
-using Newtonsoft.Json;
using VRChatApi.Classes;
using VRChatApi.Logging;
@@ -20,24 +19,18 @@ public async Task> Get(int offset = 0, int count = 20, b
HttpResponseMessage response = await Global.HttpClient.GetAsync($"auth/user/friends?apiKey={Global.ApiKey}&offset={offset}&n={count}&offline={offline.ToString().ToLowerInvariant()}");
- List res = null;
-
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject>(json);
- }
-
- return res;
+ return await Utils.ParseResponse>(response);
}
- public async Task SendRequest(string userId, string fromWho)
+ public async Task SendRequest(string userId, string fromWho = "Me")
{
Logger.Debug(() => $"Sending friend request to {userId} from {fromWho}");
- JObject json = new JObject();
- json["type"] = "friendrequest";
- json["message"] = $"{fromWho} wants to be your friend";
+
+ JObject json = new JObject()
+ {
+ { "type", "friendrequest" },
+ { "message", $"{fromWho} wants to be your friend" }
+ };
Logger.Debug(() => $"Prepared JSON to post: {json}");
@@ -46,50 +39,48 @@ public async Task SendRequest(string userId, string fromWh
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = await Global.HttpClient.PostAsync($"user/{userId}/notification?apiKey={Global.ApiKey}", content);
-
-
- NotificationResponse res = null;
- if (response.IsSuccessStatusCode)
- {
- var receivedJson = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {receivedJson}");
- res = JsonConvert.DeserializeObject(receivedJson);
- }
-
- return res;
+ return await Utils.ParseResponse(response);
}
- // TODO: proper return type, need to document
- public async Task DeleteFriend(string userId)
+ public async Task DeleteFriend(string userId)
{
HttpResponseMessage response = await Global.HttpClient.DeleteAsync($"auth/user/friends/{userId}?apiKey={Global.ApiKey}");
- string res = "";
+ return Utils.ParseResponse(response) != null;
+ }
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = json;
- }
+ public async Task AcceptFriend(string userId)
+ {
+ HttpResponseMessage response = await Global.HttpClient.PutAsync($"auth/user/notifications/{userId}/accept?apiKey={Global.ApiKey}", new StringContent(""));
- return res;
+ return Utils.ParseResponse(response) != null;
}
- // TODO: proper return type, need to document
- public async Task AcceptFriend(string userId)
+ public async Task SendInvite(string userId, string worldInstanceId = "", string worldName = "my world", string hiddenMessage = "")
{
- HttpResponseMessage response = await Global.HttpClient.PutAsync($"auth/user/notifications/{userId}/accept?apiKey={Global.ApiKey}", new StringContent(""));
+ JObject json = new JObject() {
+ { "type", "invite" },
+ { "message", hiddenMessage },
+ { "details", new JObject() {
+ { "worldId", worldInstanceId },
+ { "worldName", worldName }
+ }},
+ };
- /*string res = "";
+ Logger.Debug(() => $"Prepared JSON to post: {json}");
- if (response.IsSuccessStatusCode)
- {
- res = await response.Content.ReadAsStringAsync();
- }
+ StringContent content = new StringContent(json.ToString(), Encoding.UTF8);
- return res;*/
+ content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+
+ Logger.Debug(() => $"Prepared StringContent to post: {content}");
+
+ HttpResponseMessage response = await Global.HttpClient.PostAsync($"user/{userId}/notification?apiKey={Global.ApiKey}", content);
+
+ return await Utils.ParseResponse(response);
}
+
+ public async Task SendMessage(string userId, string message, string hiddenMessage = "") => await SendInvite(userId, worldName: message, hiddenMessage: hiddenMessage);
}
}
diff --git a/VRChatApi/VRChatApi/Endpoints/ModerationsApi.cs b/VRChatApi/VRChatApi/Endpoints/ModerationsApi.cs
index a18d5d7..f41f1eb 100644
--- a/VRChatApi/VRChatApi/Endpoints/ModerationsApi.cs
+++ b/VRChatApi/VRChatApi/Endpoints/ModerationsApi.cs
@@ -1,10 +1,9 @@
-using System;
+using Newtonsoft.Json.Linq;
using System.Collections.Generic;
-using System.Linq;
using System.Net.Http;
+using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
-using Newtonsoft.Json;
using VRChatApi.Classes;
using VRChatApi.Logging;
@@ -17,35 +16,45 @@ public class ModerationsApi
public async Task> GetPlayerModerations()
{
Logger.Trace(() => "Get list of moderations made by current user");
- HttpResponseMessage response = await Global.HttpClient.GetAsync("auth/user/playermoderations");
-
- List res = null;
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject>(json);
- }
+ HttpResponseMessage response = await Global.HttpClient.GetAsync("auth/user/playermoderations");
- return res;
+ return await Utils.ParseResponse>(response);
}
public async Task> GetPlayerModerated()
{
Logger.Trace(() => "Get list of moderations made against current user");
+
HttpResponseMessage response = await Global.HttpClient.GetAsync("auth/user/playermoderated");
- List res = null;
+ return await Utils.ParseResponse>(response);
+ }
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject>(json);
- }
- return res;
+ public async Task BlockUser(string userId)
+ {
+ JObject json = new JObject() {
+ { "blocked", userId }
+ };
+ Logger.Debug(() => $"Prepared JSON to post: {json}");
+ StringContent content = new StringContent(json.ToString(), Encoding.UTF8);
+ content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+ HttpResponseMessage response = await Global.HttpClient.PostAsync($"auth/user/blocks?apiKey={Global.ApiKey}", content);
+ return await Utils.ParseResponse(response);
+ }
+
+ public async Task UnblockUser(string userId)
+ {
+ JObject json = new JObject() {
+ { "moderated", userId },
+ { "type", "block" }
+ };
+ Logger.Debug(() => $"Prepared JSON to put: {json}");
+ StringContent content = new StringContent(json.ToString(), Encoding.UTF8);
+ content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+ HttpResponseMessage response = await Global.HttpClient.PutAsync($"auth/user/unplayermoderate?apiKey={Global.ApiKey}", content);
+ return await Utils.ParseResponse(response);
}
}
}
diff --git a/VRChatApi/VRChatApi/Endpoints/NotificationsAPI.cs b/VRChatApi/VRChatApi/Endpoints/NotificationsAPI.cs
new file mode 100644
index 0000000..d7c72ce
--- /dev/null
+++ b/VRChatApi/VRChatApi/Endpoints/NotificationsAPI.cs
@@ -0,0 +1,32 @@
+using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using VRChatApi.Classes;
+using VRChatApi.Logging;
+using System;
+
+namespace VRChatApi.Endpoints
+{
+ public class NotificationsAPI
+ {
+ private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();
+ public async Task> GetAll(string type = "all", bool sent = false, DateTime? after = null)
+ {
+ var url = $"auth/user/notifications?apiKey={Global.ApiKey}&type={type}&sent={sent}";
+ if (after != null) url += $"&after={after}";
+ HttpResponseMessage response = await Global.HttpClient.GetAsync(url);
+ List res = null;
+ if (response.IsSuccessStatusCode)
+ {
+ var receivedJson = await response.Content.ReadAsStringAsync();
+ Console.WriteLine($"JSON received: {receivedJson}");
+ res = JsonConvert.DeserializeObject>(receivedJson);
+ }
+ return res;
+ }
+ }
+}
diff --git a/VRChatApi/VRChatApi/Endpoints/RemoteConfig.cs b/VRChatApi/VRChatApi/Endpoints/RemoteConfig.cs
index 252ecc7..ff7bfa7 100644
--- a/VRChatApi/VRChatApi/Endpoints/RemoteConfig.cs
+++ b/VRChatApi/VRChatApi/Endpoints/RemoteConfig.cs
@@ -1,7 +1,5 @@
-using System;
-using System.Net.Http;
+using System.Net.Http;
using System.Threading.Tasks;
-using Newtonsoft.Json;
using VRChatApi.Classes;
using VRChatApi.Logging;
@@ -14,18 +12,14 @@ public class RemoteConfig
public async Task Get()
{
Logger.Trace(() => "Getting remote config");
+
HttpResponseMessage response = await Global.HttpClient.GetAsync("config");
- ConfigResponse res = null;
+ ConfigResponse res = await Utils.ParseResponse(response);
+
+ Global.ApiKey = res.clientApiKey;
- if (response.IsSuccessStatusCode)
- {
- var json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject(json);
- Global.ApiKey = res.clientApiKey;
- Logger.Info(() => $"API key has been set to: {Global.ApiKey}");
- }
+ Logger.Info(() => $"API key has been set to: {res.clientApiKey}");
return res;
}
diff --git a/VRChatApi/VRChatApi/Endpoints/UserApi.cs b/VRChatApi/VRChatApi/Endpoints/UserApi.cs
index 5fd15d3..11c010f 100644
--- a/VRChatApi/VRChatApi/Endpoints/UserApi.cs
+++ b/VRChatApi/VRChatApi/Endpoints/UserApi.cs
@@ -21,6 +21,7 @@ public class UserApi
public UserApi(string username, string password)
{
Logger.Trace(() => $"Entering {nameof(UserApi)} constructor with username: {username}");
+
Username = username;
Password = password;
}
@@ -28,35 +29,25 @@ public UserApi(string username, string password)
public async Task Login()
{
Logger.Trace(() => "Getting current user details");
- HttpResponseMessage response = await Global.HttpClient.GetAsync($"auth/user?apiKey={Global.ApiKey}");
-
- UserResponse res = null;
- if (response.IsSuccessStatusCode)
- {
- string json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject(json);
- }
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"auth/user?apiKey={Global.ApiKey}");
- return res;
+ return await Utils.ParseResponse(response);
}
public async Task Register(string username, string password, string email, string birthday = null, string acceptedTOSVersion = null)
{
Logger.Debug(() => $"Registering new user with {nameof(username)} = {username}, {nameof(email)} = {email}, {nameof(birthday)} = {birthday}, {nameof(acceptedTOSVersion)} = {acceptedTOSVersion}");
- JObject json = new JObject();
- json["username"] = username;
- json["password"] = password;
- if (email != null)
- json["email"] = email;
-
- if (birthday != null )
- json["birthday"] = birthday;
+ JObject json = new JObject()
+ {
+ { "username", username },
+ { "password", password }
+ };
- if (acceptedTOSVersion != null)
- json["acceptedTOSVersion"] = acceptedTOSVersion;
+ json.AddIfNotNull("email", email);
+ json.AddIfNotNull("birthday", birthday);
+ json.AddIfNotNull("acceptedTOSVersion", acceptedTOSVersion);
Logger.Debug(() => $"Prepared JSON to post: {json}");
@@ -66,51 +57,38 @@ public async Task Register(string username, string password, strin
HttpResponseMessage response = await Global.HttpClient.PostAsync($"auth/register?apiKey={Global.ApiKey}", content);
- UserResponse res = null;
+ return await Utils.ParseResponse(response);
+ }
- if (response.IsSuccessStatusCode)
- {
- var receivedJson = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {receivedJson}");
- res = JsonConvert.DeserializeObject(receivedJson);
- }
+ public async Task> Search(string pattern, int limit = 100, int offset = 0)
+ {
+ Logger.Debug(() => $"Searching user info with pattern: {pattern}");
- return res;
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"users/?apiKey={Global.ApiKey}&n={limit}&offset={offset}&search={pattern}");
+
+ return await Utils.ParseResponse>(response);
}
public async Task GetById(string userId)
{
Logger.Debug(() => $"Getting user info with ID: {userId}");
- HttpResponseMessage response = await Global.HttpClient.GetAsync($"users/{userId}?apiKey={Global.ApiKey}");
- UserBriefResponse res = null;
-
- if (response.IsSuccessStatusCode)
- {
- string json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject(json);
- }
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"users/{userId}?apiKey={Global.ApiKey}");
- return res;
+ return await Utils.ParseResponse(response);
}
- public async Task UpdateInfo(string userId, string email = null, string birthday = null, string acceptedTOSVersion = null, List tags = null)
+ public async Task UpdateInfo(string userId, string email = null, string birthday = null, string acceptedTOSVersion = null, List tags = null, string status = null, string statusDescription = null)
{
- Logger.Debug(() => $"Updating user info for {nameof(userId)} = {userId} with {nameof(email)} = {email}, {nameof(birthday)} = {birthday}, {nameof(acceptedTOSVersion)} = {acceptedTOSVersion}, {nameof(tags)} = {tags}");
- JObject json = new JObject();
-
- if (email != null)
- json["email"] = email;
-
- if (birthday != null)
- json["birthday"] = birthday;
+ Logger.Debug(() => $"Updating user info for {nameof(userId)} = {userId} with {nameof(email)} = {email}, {nameof(birthday)} = {birthday}, {nameof(acceptedTOSVersion)} = {acceptedTOSVersion}, {nameof(tags)} = {tags}, {nameof(status)} = {status}, {nameof(statusDescription)} = {statusDescription}");
- if (acceptedTOSVersion != null)
- json["acceptedTOSVersion"] = acceptedTOSVersion;
-
- if (tags != null)
- json["tags"] = JToken.FromObject(tags);
+ JObject json = new JObject();
+ json.AddIfNotNull("email", email);
+ json.AddIfNotNull("birthday", birthday);
+ json.AddIfNotNull("acceptedTOSVersion", acceptedTOSVersion);
+ if (tags != null) json.Add("tags", JToken.FromObject(tags));
+ json.AddIfNotNull("status", status);
+ json.AddIfNotNull("statusDescription", statusDescription);
Logger.Debug(() => $"Prepared JSON to put: {json}");
@@ -120,16 +98,7 @@ public async Task UpdateInfo(string userId, string email = null, s
HttpResponseMessage response = await Global.HttpClient.PutAsync($"users/{userId}?apiKey={Global.ApiKey}", content);
- UserResponse res = null;
-
- if (response.IsSuccessStatusCode)
- {
- var receivedJson = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {receivedJson}");
- res = JsonConvert.DeserializeObject(receivedJson);
- }
-
- return res;
+ return await Utils.ParseResponse(response);
}
}
}
diff --git a/VRChatApi/VRChatApi/Endpoints/WorldAPI.cs b/VRChatApi/VRChatApi/Endpoints/WorldAPI.cs
index 5de98cc..ccd059d 100644
--- a/VRChatApi/VRChatApi/Endpoints/WorldAPI.cs
+++ b/VRChatApi/VRChatApi/Endpoints/WorldAPI.cs
@@ -23,21 +23,14 @@ public async Task Get(string id)
HttpResponseMessage response = await Global.HttpClient.GetAsync($"worlds/{id}?apiKey={Global.ApiKey}");
- WorldResponse res = null;
+ var res = await Utils.ParseResponse(response);
- if (response.IsSuccessStatusCode)
+ // parse instances
+ res.instances = res._instances.Select(data => new WorldInstance()
{
- string json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject(json);
-
- // Parse instances.
- res.instances = res._instances.Select(data => new WorldInstance()
- {
- id = (string)data[0],
- occupants = (int)data[1]
- }).ToList();
- }
+ id = (string)data[0],
+ occupants = (int)data[1]
+ }).ToList();
return res;
}
@@ -48,7 +41,9 @@ public async Task> Search(WorldGroups? endpoint = null,
ReleaseStatus? releaseStatus = null, int offset = 0, int count = 20)
{
Logger.Debug(() => "Getting world list");
+
var param = new StringBuilder();
+
param.Append($"&n={count}");
param.Append($"&offset={offset}");
@@ -73,19 +68,37 @@ public async Task> Search(WorldGroups? endpoint = null,
}
if (user.HasValue)
+ {
param.Append($"&user={user.Value.ToString().ToLowerInvariant()}");
+ }
+
if (!string.IsNullOrEmpty(userId))
+ {
param.Append($"&userId={userId}");
+ }
+
if (!string.IsNullOrEmpty(keyword))
+ {
param.Append($"&search={keyword}");
+ }
+
if (!string.IsNullOrEmpty(tags))
+ {
param.Append($"&tag={tags}");
+ }
+
if (!string.IsNullOrEmpty(excludeTags))
+ {
param.Append($"¬ag={excludeTags}");
+ }
+
if (releaseStatus.HasValue)
+ {
param.Append($"&releaseStatus={releaseStatus.Value.ToString().ToLowerInvariant()}");
+ }
string baseUrl = "worlds";
+
if (endpoint.HasValue)
{
switch (endpoint.Value)
@@ -104,38 +117,22 @@ public async Task> Search(WorldGroups? endpoint = null,
HttpResponseMessage response = await Global.HttpClient.GetAsync($"{baseUrl}?apiKey={Global.ApiKey}{param.ToString()}");
- List res = null;
-
- if (response.IsSuccessStatusCode)
- {
- string json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject>(json);
- }
-
- return res;
+ return await Utils.ParseResponse>(response);
}
public async Task GetMetadata(string id)
{
Logger.Debug(() => $"Getting world metadata with ID: {id}");
- HttpResponseMessage response = await Global.HttpClient.GetAsync($"worlds/{id}/metadata?apiKey={Global.ApiKey}");
-
- WorldMetadataResponse res = null;
- if (response.IsSuccessStatusCode)
- {
- string json = await response.Content.ReadAsStringAsync();
- Logger.Debug(() => $"JSON received: {json}");
- res = JsonConvert.DeserializeObject(json);
- }
+ HttpResponseMessage response = await Global.HttpClient.GetAsync($"worlds/{id}/metadata?apiKey={Global.ApiKey}");
- return res;
+ return await Utils.ParseResponse(response);
}
public async Task GetInstance(string worldId, string instanceId)
{
Logger.Debug(() => $"Getting world instance with world ID: {worldId} and instance ID {instanceId}");
+
HttpResponseMessage response = await Global.HttpClient.GetAsync($"worlds/{worldId}/{instanceId}?apiKey={Global.ApiKey}");
WorldInstanceResponse res = null;
@@ -157,10 +154,12 @@ public async Task GetInstance(string worldId, string inst
users = (json["users"] is JArray)
? json["users"].Select(tk => tk.ToObject()).ToList() : null,
hidden = (json["hidden"] == null || json["hidden"].Type == JTokenType.Null) ? null : json["hidden"].ToString(),
- nonce = (json["nonce"] == null) ? null : json["nonce"].ToString(),
+ nonce = json["nonce"]?.ToString(),
};
}
+ response.Dispose();
+
return res;
}
}
diff --git a/VRChatApi/VRChatApi/Properties/AssemblyInfo.cs b/VRChatApi/VRChatApi/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5f28270
--- /dev/null
+++ b/VRChatApi/VRChatApi/Properties/AssemblyInfo.cs
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/VRChatApi/VRChatApi/Utils.cs b/VRChatApi/VRChatApi/Utils.cs
new file mode 100644
index 0000000..50fa39d
--- /dev/null
+++ b/VRChatApi/VRChatApi/Utils.cs
@@ -0,0 +1,79 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Net.Http;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using VRChatApi.Logging;
+using VRChatApi.Classes;
+using System.Reflection;
+using System.ComponentModel;
+
+namespace VRChatApi
+{
+ static class Utils
+ {
+ public static void AddIfNotNull(this JObject jObject, string key, string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ jObject[key] = value;
+ }
+ }
+
+ public static void AddIfNotNull(this JObject jObject, string key, JToken value)
+ {
+ if (value.HasValues)
+ {
+ jObject[key] = value;
+ }
+ }
+
+ private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();
+
+ public static async Task ParseResponse(HttpResponseMessage responseMessage) where T : class
+ {
+ T res = null;
+ /*switch (T.GetType())
+ {
+ case typeof(UserBriefResponse):
+ UserBriefResponse res = null;
+ break;
+ default:
+ break;
+ }
+ res.Raw = responseMessage;*/
+ if (responseMessage.IsSuccessStatusCode)
+ {
+ var receivedJson = await responseMessage.Content.ReadAsStringAsync();
+
+ Logger.Debug(() => $"JSON received: {receivedJson}");
+
+ res = JsonConvert.DeserializeObject(receivedJson);
+
+ }
+
+ responseMessage.Dispose();
+
+ return res;
+ }
+ }
+ static class Extensions
+ {
+ public static string GetDescription(this Enum value)
+ {
+ Type type = value.GetType();
+ string name = Enum.GetName(type, value);
+ if (name != null) {
+ FieldInfo field = type.GetField(name);
+ if (field != null) {
+ DescriptionAttribute attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
+ if (attr != null) {
+ return attr.Description;
+ }
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/VRChatApi/VRChatApi/VRChatApi.cs b/VRChatApi/VRChatApi/VRChatApi.cs
index 9819c4e..d6b8283 100644
--- a/VRChatApi/VRChatApi/VRChatApi.cs
+++ b/VRChatApi/VRChatApi/VRChatApi.cs
@@ -16,6 +16,8 @@ public class VRChatApi
public WorldApi WorldApi { get; set; }
public ModerationsApi ModerationsApi { get; set; }
public AvatarApi AvatarApi { get; set; }
+ public FavouriteApi FavouriteApi { get; set; }
+ public NotificationsAPI NotificationsAPI { get; set; }
public VRChatApi(string username, string password)
{
@@ -29,6 +31,8 @@ public VRChatApi(string username, string password)
WorldApi = new WorldApi();
ModerationsApi = new ModerationsApi();
AvatarApi = new AvatarApi();
+ FavouriteApi = new FavouriteApi();
+ NotificationsAPI = new NotificationsAPI();
// initialize http client
// TODO: use the auth cookie
@@ -43,12 +47,15 @@ public VRChatApi(string username, string password)
string authEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{UserApi.Username}:{UserApi.Password}"));
var header = Global.HttpClient.DefaultRequestHeaders;
+
if (header.Contains("Authorization"))
{
Logger.Debug(() => "Removing existing Authorization header");
header.Remove("Authorization");
}
+
header.Add("Authorization", $"Basic {authEncoded}");
+
Logger.Trace(() => $"Added new Authorization header");
}
}
diff --git a/VRChatApi/VRChatApi/VRChatApi.csproj b/VRChatApi/VRChatApi/VRChatApi.csproj
index bdc0864..bd2532b 100644
--- a/VRChatApi/VRChatApi/VRChatApi.csproj
+++ b/VRChatApi/VRChatApi/VRChatApi.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.0
@@ -13,8 +13,9 @@
all
runtime; build; native; contentfiles; analyzers
-
+
+
diff --git a/VRChatApi/VRChatApi/packages.config b/VRChatApi/VRChatApi/packages.config
new file mode 100644
index 0000000..374f45c
--- /dev/null
+++ b/VRChatApi/VRChatApi/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..39a2b6e
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [
+ "config:base"
+ ]
+}