rdiscord_sdk 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +13 -0
- data/.vscode/c_cpp_properties.json +24 -0
- data/.vscode/settings.json +102 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +46 -0
- data/INTERNALS.md +0 -0
- data/LICENSE +674 -0
- data/README.md +187 -0
- data/Rakefile +17 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ext/rdiscord_sdk/activity.cpp +297 -0
- data/ext/rdiscord_sdk/activity.h +17 -0
- data/ext/rdiscord_sdk/common.cpp +65 -0
- data/ext/rdiscord_sdk/common.h +88 -0
- data/ext/rdiscord_sdk/extconf.rb +54 -0
- data/ext/rdiscord_sdk/gem_activity_manager.cpp +273 -0
- data/ext/rdiscord_sdk/gem_activity_manager.h +8 -0
- data/ext/rdiscord_sdk/gem_user_manager.cpp +114 -0
- data/ext/rdiscord_sdk/gem_user_manager.h +8 -0
- data/ext/rdiscord_sdk/rdiscord_sdk.cpp +77 -0
- data/ext/rdiscord_sdk/rdiscord_sdk.h +17 -0
- data/ext/rdiscord_sdk/user.cpp +98 -0
- data/ext/rdiscord_sdk/user.h +19 -0
- data/lib/rdiscord_sdk/enums.rb +162 -0
- data/lib/rdiscord_sdk/rdiscord_sdk.so +0 -0
- data/lib/rdiscord_sdk/version.rb +16 -0
- data/lib/rdiscord_sdk.rb +3 -0
- data/rdiscord_sdk.gemspec +34 -0
- data/third-party/include/achievement_manager.cpp +98 -0
- data/third-party/include/achievement_manager.h +34 -0
- data/third-party/include/activity_manager.cpp +177 -0
- data/third-party/include/activity_manager.h +42 -0
- data/third-party/include/application_manager.cpp +78 -0
- data/third-party/include/application_manager.h +30 -0
- data/third-party/include/core.cpp +182 -0
- data/third-party/include/core.h +64 -0
- data/third-party/include/discord.h +16 -0
- data/third-party/include/event.h +59 -0
- data/third-party/include/ffi.h +942 -0
- data/third-party/include/image_manager.cpp +57 -0
- data/third-party/include/image_manager.h +28 -0
- data/third-party/include/lobby_manager.cpp +547 -0
- data/third-party/include/lobby_manager.h +88 -0
- data/third-party/include/network_manager.cpp +103 -0
- data/third-party/include/network_manager.h +63 -0
- data/third-party/include/overlay_manager.cpp +112 -0
- data/third-party/include/overlay_manager.h +33 -0
- data/third-party/include/relationship_manager.cpp +90 -0
- data/third-party/include/relationship_manager.h +32 -0
- data/third-party/include/storage_manager.cpp +158 -0
- data/third-party/include/storage_manager.h +46 -0
- data/third-party/include/store_manager.cpp +160 -0
- data/third-party/include/store_manager.h +38 -0
- data/third-party/include/types.cpp +769 -0
- data/third-party/include/types.h +492 -0
- data/third-party/include/user_manager.cpp +80 -0
- data/third-party/include/user_manager.h +31 -0
- data/third-party/include/voice_manager.cpp +124 -0
- data/third-party/include/voice_manager.h +37 -0
- data/third-party/lib/x86/discord_game_sdk.dll +0 -0
- data/third-party/lib/x86/discord_game_sdk.dll.lib +0 -0
- data/third-party/lib/x86_64/discord_game_sdk.bundle +0 -0
- data/third-party/lib/x86_64/discord_game_sdk.dll +0 -0
- data/third-party/lib/x86_64/discord_game_sdk.dll.lib +0 -0
- data/third-party/lib/x86_64/discord_game_sdk.dylib +0 -0
- data/third-party/lib/x86_64/discord_game_sdk.so +0 -0
- metadata +114 -0
data/README.md
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
# R(uby) Discord SDK
|
2
|
+
|
3
|
+
This is a Ruby gem that implements bindings to the [Discord Game SDK](https://discord.com/developers/docs/game-sdk/discord).
|
4
|
+
It is intended to be used in [ModShot](https://github.com/Astrabit-ST/Modshot-Core), although will work in any ruby application.
|
5
|
+
|
6
|
+
## Whats the difference between this and ruby_discord_game_sdk?
|
7
|
+
|
8
|
+
Well, [ruby_discord_game_sdk](https://github.com/rkevin-arch/ruby_discord_game_sdk) is written in pure C, making it very hard to understand and interpret.
|
9
|
+
This means it's very difficult to understand how it works, what it does, and to add new features.
|
10
|
+
rdiscord_sdk is instead built in C++ meaning it's easier to abstract, and to modify the source. The name may be obtuse, but it sure as hell isn't internally.
|
11
|
+
My goal is to provide extra levels of abstraction over ruby_discord_game_sdk, and provide full functionality as well. Wether that will happen, I'm not sure.
|
12
|
+
|
13
|
+
## Disclaimer
|
14
|
+
Some portions of code are untested because they can be extremely hard to test, namely events.
|
15
|
+
Keep that in mind.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
This gem (at the moment) exposes SDK functions without much abstraction, so as long as you can grasp C#, you should be able to transfer the example code to ruby code.
|
20
|
+
There are a couple of minor differences, such as the lack of a need to initialize managers (C++ Discord SDK bindings automatically do that for you).
|
21
|
+
|
22
|
+
- Setting up the SDK is the same as ruby_discord_game_sdk `Discord::init(client_id, flags)`
|
23
|
+
- Enums are just constants inside lib/rdiscord_sdk/enums.rb (So `Discord.Result.Ok` ~> `Discord::Result::Ok`)
|
24
|
+
- The module for SDK functions is under `Discord`, not `DiscordSDK`
|
25
|
+
- Callbacks are method blocks
|
26
|
+
- Events are also method blocks
|
27
|
+
- Pending callbacks and events are accessible
|
28
|
+
- Some functions return an array, usually the result being at [0] and an object at [1] (such as Discord::UserManager.get_current_user)
|
29
|
+
|
30
|
+
As mentioned above, some functions return arrays. An easy way to deal with these would be to:
|
31
|
+
```rb
|
32
|
+
result, user = Discord::UserManager.get_current_user
|
33
|
+
```
|
34
|
+
It's not the best, but it works. I don't want to discard a result, in case you ever want to know what went wrong.
|
35
|
+
If you don't want the result, you can just do:
|
36
|
+
```rb
|
37
|
+
_, user = Discord::UserManager.get_current_user
|
38
|
+
```
|
39
|
+
`_` is widely understood as a dummy variable, so it's good practice to use it when you don't care about a specific return value.
|
40
|
+
|
41
|
+
## Callbacks & Events
|
42
|
+
|
43
|
+
As mentioned before, callbacks and events are method blocks and procs, and are not usually required. If you've coded ruby before, just use them how you normally would.
|
44
|
+
Generally, when you see `() => {}` in the SDK documentation, that is referring to a callback or event, and so you should substitute it with a block instead.
|
45
|
+
|
46
|
+
Docs:
|
47
|
+
```cs
|
48
|
+
var userManager = discord.GetUserManager();
|
49
|
+
var activity = new Discord.Activity
|
50
|
+
activityManager.UpdateActivity(activity, (result) =>
|
51
|
+
{
|
52
|
+
if (result == Discord.Result.Ok)
|
53
|
+
{
|
54
|
+
Console.WriteLine("Success!");
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
Console.WriteLine("Failed");
|
59
|
+
}
|
60
|
+
}
|
61
|
+
```
|
62
|
+
rdiscord_sdk equivalent:
|
63
|
+
```rb
|
64
|
+
Discord::ActivityManager.update_activity(Discord::Activity.new) do |result|
|
65
|
+
if result == Discord::Result::Ok
|
66
|
+
puts "Success!"
|
67
|
+
else
|
68
|
+
puts "Failed"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
If no block is provided, and an error occurs, it should be logged to stderr. (or your log hook if that is set up)
|
74
|
+
|
75
|
+
Events work a little bit differently than in the SDK docs. As far as I can tell, the docs don't cover "connecting" or "disconnecting".
|
76
|
+
Events require you to "connect" to them, meaning you can subscribe multiple blocks to any single event. (iirc the cap is 4?)
|
77
|
+
When you add something to an event, it will return a token, an identifier to the block passed into the event, which **must** be used when removing blocks from an event.
|
78
|
+
It's sort of like a subscriber system, where things can subscribe to an event, and then unsubscribe from said event at any point.
|
79
|
+
|
80
|
+
Events and pending callbacks are stored in a global array and hash respectively, if you ever need to access them for some reason.
|
81
|
+
**I would not suggest trying to modify them.** It will inevitably cause bad problems.
|
82
|
+
|
83
|
+
C# code:
|
84
|
+
```cs
|
85
|
+
activityManager.OnActivityJoin += secret => {
|
86
|
+
Console.WriteLine("OnJoin {0}", secret);
|
87
|
+
}
|
88
|
+
```
|
89
|
+
rdiscord_sdk equivalent:
|
90
|
+
```rb
|
91
|
+
token = Discord::ActivityManager.on_activity_join_connect do |secret|
|
92
|
+
puts "OnJoin #{secret}"
|
93
|
+
end
|
94
|
+
|
95
|
+
Discord::ActivtyManager.on_activity_join_disconnect(token) # I'm not sure what the C# equivalent is
|
96
|
+
```
|
97
|
+
|
98
|
+
## Installation
|
99
|
+
|
100
|
+
Add this line to your application's Gemfile:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
gem 'rdiscord_sdk'
|
104
|
+
```
|
105
|
+
|
106
|
+
And then execute:
|
107
|
+
|
108
|
+
$ bundle install
|
109
|
+
|
110
|
+
Or install it yourself as:
|
111
|
+
|
112
|
+
$ gem install rdiscord_sdk
|
113
|
+
|
114
|
+
|
115
|
+
## Development
|
116
|
+
|
117
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
118
|
+
|
119
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
120
|
+
|
121
|
+
## License
|
122
|
+
|
123
|
+
The gem is available as open source under the terms of the [GPL-3]() license.
|
124
|
+
|
125
|
+
This gem also uses the [Discord SDK](https://discord.com/developers/docs/game-sdk/discord), which is proprietary. Everything under `third_party/` is owned by Discord.
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Speak2Erase/rdiscord_sdk.
|
130
|
+
|
131
|
+
## Development Progress
|
132
|
+
|
133
|
+
### Data Classes
|
134
|
+
|
135
|
+
- [x] DiscordUser
|
136
|
+
- [ ] DiscordOAuth2Token
|
137
|
+
- [ ] DiscordImageHandle
|
138
|
+
- [ ] DiscordImageDimensions
|
139
|
+
- [x] DiscordActivityTimestamps
|
140
|
+
- [x] DiscordActivityAssets
|
141
|
+
- [x] DiscordPartySize
|
142
|
+
- [x] DiscordActivityParty
|
143
|
+
- [x] DiscordActivitySecrets
|
144
|
+
- [x] DiscordActivity
|
145
|
+
- [ ] DiscordPresence
|
146
|
+
- [ ] DiscordRelationship
|
147
|
+
- [ ] DiscordLobby
|
148
|
+
- [ ] DiscordFileStat
|
149
|
+
- [ ] DiscordEntitlement
|
150
|
+
- [ ] DiscordSkuPrive
|
151
|
+
- [ ] DiscordSku
|
152
|
+
- [ ] DiscordInputMode
|
153
|
+
- [ ] DiscordUserAchievement
|
154
|
+
|
155
|
+
### Managers implemented
|
156
|
+
- [ ] ApplicationManager
|
157
|
+
- [x] UserManager
|
158
|
+
- [ ] ImageManager
|
159
|
+
- [x] ActivityManager
|
160
|
+
- [ ] RelationshipManager
|
161
|
+
- [ ] LobbyManager
|
162
|
+
- [ ] NetworkManager
|
163
|
+
- [ ] OverlayManager
|
164
|
+
- [ ] StorageManager
|
165
|
+
- [ ] StoreManager
|
166
|
+
- [ ] VoiceManager
|
167
|
+
- [ ] AchievementManager
|
168
|
+
|
169
|
+
### Others
|
170
|
+
- [ ] Core functionality
|
171
|
+
- [x] Initialization
|
172
|
+
- [ ] Teardown
|
173
|
+
- [x] Run callbacks
|
174
|
+
- [x] Log hooks
|
175
|
+
- [x] All enums
|
176
|
+
- [ ] DiscordLobbyTransaction
|
177
|
+
- [ ] DiscordLobbySearchQuery
|
178
|
+
- [x] Events
|
179
|
+
- [x] UserEvents
|
180
|
+
- [x] ActivityEvents
|
181
|
+
- [ ] RelationshipEvents
|
182
|
+
- [ ] LobbyEvents
|
183
|
+
- [ ] NetworkEvents
|
184
|
+
- [ ] OverlayEvents
|
185
|
+
- [ ] StoreEvents
|
186
|
+
- [ ] VoiceEvents
|
187
|
+
- [ ] AchievementEvents
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rubocop/rake_task"
|
5
|
+
require "rake/extensiontask"
|
6
|
+
|
7
|
+
RuboCop::RakeTask.new
|
8
|
+
|
9
|
+
task default: :rubocop
|
10
|
+
|
11
|
+
task build: :compile
|
12
|
+
|
13
|
+
Rake::ExtensionTask.new("rdiscord_sdk") do |ext|
|
14
|
+
ext.lib_dir = "lib/rdiscord_sdk"
|
15
|
+
end
|
16
|
+
|
17
|
+
task default: %i[clobber compile]
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "rdiscord_sdk"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
#include "activity.h"
|
2
|
+
#include <rice/rice.hpp>
|
3
|
+
#include "discord.h"
|
4
|
+
#include "common.h"
|
5
|
+
#include <cstdint>
|
6
|
+
using namespace Rice;
|
7
|
+
|
8
|
+
Class rb_cActivity;
|
9
|
+
|
10
|
+
DEF_TYPE_CUSTOMTYPENAME(discord::Activity, Activity_rbType);
|
11
|
+
|
12
|
+
Object rb_activity_initialize(Object self) {
|
13
|
+
discord::Activity* activity = new discord::Activity();
|
14
|
+
setPrivateData(self, activity);
|
15
|
+
|
16
|
+
return self;
|
17
|
+
}
|
18
|
+
|
19
|
+
int rb_activity_get_type(Object self) {
|
20
|
+
GET_ACTIVITY(self);
|
21
|
+
|
22
|
+
return (int) activity->GetType();
|
23
|
+
}
|
24
|
+
|
25
|
+
Object rb_activity_set_type(Object self, int type) {
|
26
|
+
GET_ACTIVITY(self);
|
27
|
+
|
28
|
+
activity->SetType((discord::ActivityType) type);
|
29
|
+
|
30
|
+
return Qnil;
|
31
|
+
}
|
32
|
+
|
33
|
+
std::int64_t rb_activity_get_application_id(Object self) {
|
34
|
+
GET_ACTIVITY(self);
|
35
|
+
|
36
|
+
return activity->GetApplicationId();
|
37
|
+
}
|
38
|
+
|
39
|
+
Object rb_activity_set_application_id(Object self, std::int64_t id) {
|
40
|
+
GET_ACTIVITY(self);
|
41
|
+
|
42
|
+
activity->SetApplicationId(id);
|
43
|
+
|
44
|
+
return Qnil;
|
45
|
+
}
|
46
|
+
|
47
|
+
const char* rb_activity_get_name(Object self) {
|
48
|
+
GET_ACTIVITY(self);
|
49
|
+
|
50
|
+
return activity->GetName();
|
51
|
+
}
|
52
|
+
|
53
|
+
Object rb_activity_set_name(Object self, const char* name) {
|
54
|
+
GET_ACTIVITY(self);
|
55
|
+
|
56
|
+
activity->SetName(name);
|
57
|
+
|
58
|
+
return Qnil;
|
59
|
+
}
|
60
|
+
|
61
|
+
const char* rb_activity_get_state(Object self) {
|
62
|
+
GET_ACTIVITY(self);
|
63
|
+
|
64
|
+
return activity->GetState();
|
65
|
+
}
|
66
|
+
|
67
|
+
Object rb_activity_set_state(Object self, const char* state) {
|
68
|
+
GET_ACTIVITY(self);
|
69
|
+
|
70
|
+
activity->SetState(state);
|
71
|
+
|
72
|
+
return Qnil;
|
73
|
+
}
|
74
|
+
|
75
|
+
const char* rb_activity_get_details(Object self) {
|
76
|
+
GET_ACTIVITY(self);
|
77
|
+
|
78
|
+
return activity->GetDetails();
|
79
|
+
}
|
80
|
+
|
81
|
+
Object rb_activity_set_details(Object self, const char* details) {
|
82
|
+
GET_ACTIVITY(self);
|
83
|
+
|
84
|
+
activity->SetDetails(details);
|
85
|
+
|
86
|
+
return Qnil;
|
87
|
+
}
|
88
|
+
|
89
|
+
bool rb_activity_get_instance(Object self) {
|
90
|
+
GET_ACTIVITY(self);
|
91
|
+
|
92
|
+
return activity->GetInstance();
|
93
|
+
}
|
94
|
+
|
95
|
+
Object rb_activity_set_instance(Object self, bool instance) {
|
96
|
+
GET_ACTIVITY(self);
|
97
|
+
|
98
|
+
activity->SetInstance(instance);
|
99
|
+
|
100
|
+
return Qnil;
|
101
|
+
}
|
102
|
+
|
103
|
+
std::int64_t rb_activity_timestamp_get_timestamp_start(Object self) {
|
104
|
+
GET_ACTIVITY(self);
|
105
|
+
|
106
|
+
return activity->GetTimestamps().GetStart();
|
107
|
+
}
|
108
|
+
|
109
|
+
Object rb_activity_timestamp_set_timestamp_start(Object self, std::int64_t start) {
|
110
|
+
GET_ACTIVITY(self);
|
111
|
+
|
112
|
+
activity->GetTimestamps().SetStart(start);
|
113
|
+
|
114
|
+
return Qnil;
|
115
|
+
}
|
116
|
+
|
117
|
+
std::int64_t rb_activity_timestamp_get_timestamp_end(Object self) {
|
118
|
+
GET_ACTIVITY(self);
|
119
|
+
|
120
|
+
return activity->GetTimestamps().GetEnd();
|
121
|
+
}
|
122
|
+
|
123
|
+
Object rb_activity_timestamp_set_timestamp_end(Object self, std::int64_t end) {
|
124
|
+
GET_ACTIVITY(self);
|
125
|
+
|
126
|
+
activity->GetTimestamps().SetEnd(end);
|
127
|
+
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
const char* rb_activity_assets_get_large_image(Object self) {
|
132
|
+
GET_ACTIVITY(self);
|
133
|
+
|
134
|
+
return activity->GetAssets().GetLargeImage();
|
135
|
+
}
|
136
|
+
|
137
|
+
Object rb_activity_assets_set_large_image(Object self, const char* largeImage) {
|
138
|
+
GET_ACTIVITY(self);
|
139
|
+
|
140
|
+
activity->GetAssets().SetLargeImage(largeImage);
|
141
|
+
|
142
|
+
return Qnil;
|
143
|
+
}
|
144
|
+
|
145
|
+
const char* rb_activity_assets_get_large_text(Object self) {
|
146
|
+
GET_ACTIVITY(self);
|
147
|
+
|
148
|
+
return activity->GetAssets().GetLargeText();
|
149
|
+
}
|
150
|
+
|
151
|
+
Object rb_activity_assets_set_large_text(Object self, const char* largeText) {
|
152
|
+
GET_ACTIVITY(self);
|
153
|
+
|
154
|
+
activity->GetAssets().SetLargeText(largeText);
|
155
|
+
|
156
|
+
return Qnil;
|
157
|
+
}
|
158
|
+
|
159
|
+
const char* rb_activity_assets_get_small_image(Object self) {
|
160
|
+
GET_ACTIVITY(self);
|
161
|
+
|
162
|
+
return activity->GetAssets().GetSmallImage();
|
163
|
+
}
|
164
|
+
|
165
|
+
Object rb_activity_assets_set_small_image(Object self, const char* smallImage) {
|
166
|
+
GET_ACTIVITY(self);
|
167
|
+
|
168
|
+
activity->GetAssets().SetSmallImage(smallImage);
|
169
|
+
|
170
|
+
return Qnil;
|
171
|
+
}
|
172
|
+
|
173
|
+
const char* rb_activity_assets_get_small_text(Object self) {
|
174
|
+
GET_ACTIVITY(self);
|
175
|
+
|
176
|
+
return activity->GetAssets().GetSmallText();
|
177
|
+
}
|
178
|
+
|
179
|
+
Object rb_activity_assets_set_small_text(Object self, const char* smallText) {
|
180
|
+
GET_ACTIVITY(self);
|
181
|
+
|
182
|
+
activity->GetAssets().SetSmallText(smallText);
|
183
|
+
|
184
|
+
return Qnil;
|
185
|
+
}
|
186
|
+
|
187
|
+
const char* rb_activity_party_get_party_id(Object self) {
|
188
|
+
GET_ACTIVITY(self);
|
189
|
+
|
190
|
+
return activity->GetParty().GetId();
|
191
|
+
}
|
192
|
+
|
193
|
+
Object rb_activity_party_set_party_id(Object self, const char* id) {
|
194
|
+
GET_ACTIVITY(self);
|
195
|
+
|
196
|
+
activity->GetParty().SetId(id);
|
197
|
+
|
198
|
+
return Qnil;
|
199
|
+
}
|
200
|
+
|
201
|
+
std::int32_t rb_activity_party_get_party_size(Object self) {
|
202
|
+
GET_ACTIVITY(self);
|
203
|
+
|
204
|
+
return activity->GetParty().GetSize().GetCurrentSize();
|
205
|
+
}
|
206
|
+
|
207
|
+
Object rb_activity_party_set_party_size(Object self, std::int32_t size) {
|
208
|
+
GET_ACTIVITY(self);
|
209
|
+
|
210
|
+
activity->GetParty().GetSize().SetCurrentSize(size);
|
211
|
+
|
212
|
+
return Qnil;
|
213
|
+
}
|
214
|
+
|
215
|
+
std::int32_t rb_activity_party_get_party_max(Object self) {
|
216
|
+
GET_ACTIVITY(self);
|
217
|
+
|
218
|
+
return activity->GetParty().GetSize().GetMaxSize();
|
219
|
+
}
|
220
|
+
|
221
|
+
Object rb_activity_party_set_party_max(Object self, std::int32_t max) {
|
222
|
+
GET_ACTIVITY(self);
|
223
|
+
|
224
|
+
activity->GetParty().GetSize().SetMaxSize(max);
|
225
|
+
|
226
|
+
return Qnil;
|
227
|
+
}
|
228
|
+
|
229
|
+
const char* rb_activity_secrets_get_secret_match(Object self) {
|
230
|
+
GET_ACTIVITY(self);
|
231
|
+
|
232
|
+
return activity->GetSecrets().GetMatch();
|
233
|
+
}
|
234
|
+
|
235
|
+
Object rb_activity_secrets_set_secret_match(Object self, const char* match) {
|
236
|
+
GET_ACTIVITY(self);
|
237
|
+
|
238
|
+
activity->GetSecrets().SetMatch(match);
|
239
|
+
|
240
|
+
return Qnil;
|
241
|
+
}
|
242
|
+
|
243
|
+
const char* rb_activity_secrets_get_secret_join(Object self) {
|
244
|
+
GET_ACTIVITY(self);
|
245
|
+
|
246
|
+
return activity->GetSecrets().GetJoin();
|
247
|
+
}
|
248
|
+
|
249
|
+
Object rb_activity_secrets_set_secret_join(Object self, const char* join) {
|
250
|
+
GET_ACTIVITY(self);
|
251
|
+
|
252
|
+
activity->GetSecrets().SetJoin(join);
|
253
|
+
|
254
|
+
return Qnil;
|
255
|
+
}
|
256
|
+
|
257
|
+
const char* rb_activity_secrets_get_secret_spectate(Object self) {
|
258
|
+
GET_ACTIVITY(self);
|
259
|
+
|
260
|
+
return activity->GetSecrets().GetSpectate();
|
261
|
+
}
|
262
|
+
|
263
|
+
Object rb_activity_secrets_set_secret_spectate(Object self, const char* spectate) {
|
264
|
+
GET_ACTIVITY(self);
|
265
|
+
|
266
|
+
activity->GetSecrets().SetSpectate(spectate);
|
267
|
+
|
268
|
+
return Qnil;
|
269
|
+
}
|
270
|
+
|
271
|
+
void rb_activity_init_class(Module module) {
|
272
|
+
rb_cActivity = define_class_under(module, "Activity");
|
273
|
+
rb_cActivity.define_method("initialize", &rb_activity_initialize);
|
274
|
+
rb_define_alloc_func(rb_cActivity, classAllocate<&Activity_rbType>);
|
275
|
+
DEF_METHOD_GET_SET(rb_cActivity, type, activity);
|
276
|
+
DEF_METHOD_GET_SET(rb_cActivity, application_id, activity);
|
277
|
+
DEF_METHOD_GET_SET(rb_cActivity, name, activity);
|
278
|
+
DEF_METHOD_GET_SET(rb_cActivity, state, activity);
|
279
|
+
DEF_METHOD_GET_SET(rb_cActivity, details, activity);
|
280
|
+
DEF_METHOD_GET_SET(rb_cActivity, instance, activity);
|
281
|
+
// Timestamps
|
282
|
+
DEF_METHOD_GET_SET(rb_cActivity, timestamp_start, activity_timestamp);
|
283
|
+
DEF_METHOD_GET_SET(rb_cActivity, timestamp_end, activity_timestamp);
|
284
|
+
// Assets
|
285
|
+
DEF_METHOD_GET_SET(rb_cActivity, large_image, activity_assets);
|
286
|
+
DEF_METHOD_GET_SET(rb_cActivity, large_text, activity_assets);
|
287
|
+
DEF_METHOD_GET_SET(rb_cActivity, small_image, activity_assets);
|
288
|
+
DEF_METHOD_GET_SET(rb_cActivity, small_text, activity_assets);
|
289
|
+
// Party
|
290
|
+
DEF_METHOD_GET_SET(rb_cActivity, party_id, activity_party);
|
291
|
+
DEF_METHOD_GET_SET(rb_cActivity, party_size, activity_party);
|
292
|
+
DEF_METHOD_GET_SET(rb_cActivity, party_max, activity_party);
|
293
|
+
// Secrets
|
294
|
+
DEF_METHOD_GET_SET(rb_cActivity, secret_match, activity_secrets);
|
295
|
+
DEF_METHOD_GET_SET(rb_cActivity, secret_join, activity_secrets);
|
296
|
+
DEF_METHOD_GET_SET(rb_cActivity, secret_spectate, activity_secrets);
|
297
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <rice/rice.hpp>
|
4
|
+
#include "rdiscord_sdk.h"
|
5
|
+
#include "discord.h"
|
6
|
+
#include "common.h"
|
7
|
+
|
8
|
+
using namespace Rice;
|
9
|
+
|
10
|
+
extern Class rb_cActivity;
|
11
|
+
void rb_activity_init_class(Module module);
|
12
|
+
|
13
|
+
#define GET_ACTIVITY(obj) \
|
14
|
+
if (!obj.is_a(rb_cActivity)) { \
|
15
|
+
rb_raise(rb_eTypeError, "Activity is not a Discord::Activity"); \
|
16
|
+
} \
|
17
|
+
discord::Activity* activity = getPrivateData<discord::Activity>(obj);
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#include "common.h"
|
2
|
+
#include <functional>
|
3
|
+
#include <iostream>
|
4
|
+
|
5
|
+
using namespace Rice;
|
6
|
+
|
7
|
+
VALUE rb_common_get_callback_proc(int args) {
|
8
|
+
if (!rb_block_given_p())
|
9
|
+
{
|
10
|
+
return Qnil;
|
11
|
+
}
|
12
|
+
VALUE proc = rb_block_proc();
|
13
|
+
if (rb_proc_arity(proc) != args) {
|
14
|
+
rb_raise(rb_eRuntimeError, "Passed block should take %d arguments, got %d instead", args, rb_proc_arity(proc));
|
15
|
+
}
|
16
|
+
rb_ary_push(rb_oPendingCallbacks, proc);
|
17
|
+
return proc;
|
18
|
+
}
|
19
|
+
|
20
|
+
VALUE rb_common_get_event_proc(int args) {
|
21
|
+
if (!rb_block_given_p())
|
22
|
+
{
|
23
|
+
return Qnil;
|
24
|
+
}
|
25
|
+
|
26
|
+
VALUE proc = rb_block_proc();
|
27
|
+
if (rb_proc_arity(proc) != args) {
|
28
|
+
rb_raise(rb_eRuntimeError, "Passed block should take %d arguments, got %d instead", args, rb_proc_arity(proc));
|
29
|
+
}
|
30
|
+
return proc;
|
31
|
+
}
|
32
|
+
|
33
|
+
void rb_common_add_proc_to_hash(VALUE key, VALUE proc) {
|
34
|
+
rb_hash_aset(rb_oProcEvents, key, proc);
|
35
|
+
}
|
36
|
+
|
37
|
+
VALUE rb_result_to_obj(discord::Result result) {
|
38
|
+
return INT2NUM((int) result);
|
39
|
+
}
|
40
|
+
|
41
|
+
VALUE rb_discord_call_proc(VALUE ary) {
|
42
|
+
VALUE proc = rb_ary_shift(ary);
|
43
|
+
return rb_proc_call(proc, ary);
|
44
|
+
}
|
45
|
+
|
46
|
+
/* Discord's C++ API doesn't have callback data, so this is the easiest way (i could think of) to make a callback know what proc it has */
|
47
|
+
std::function<void(discord::Result)> rb_discord_callback_wrapper_basic(VALUE proc) {
|
48
|
+
std::function<void(discord::Result)> fn = [proc](discord::Result result){
|
49
|
+
if (proc == Qnil)
|
50
|
+
return;
|
51
|
+
|
52
|
+
if (!rb_obj_is_kind_of(proc, rb_cProc)) {
|
53
|
+
rb_raise(rb_eTypeError, "Proc expected in callback, got %d instead", rb_obj_classname(proc));
|
54
|
+
}
|
55
|
+
|
56
|
+
rb_ary_delete(rb_oPendingCallbacks, proc);
|
57
|
+
VALUE ary = rb_ary_new_from_args(2, proc, INT2NUM((int) result));
|
58
|
+
|
59
|
+
int state;
|
60
|
+
rb_protect(rb_discord_call_proc, ary, &state);
|
61
|
+
LOG_ERROR_IF_STATE;
|
62
|
+
};
|
63
|
+
return fn;
|
64
|
+
}
|
65
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "rdiscord_sdk.h"
|
4
|
+
#include <exception>
|
5
|
+
|
6
|
+
#define BOOL2RB(val) ((val) ? Qtrue : Qfalse)
|
7
|
+
|
8
|
+
#define CHECK_CORE_INITIALIZED \
|
9
|
+
if (!DiscordSDK.core) \
|
10
|
+
rb_raise(rb_eRuntimeError, "The Discord SDK core is not initialized!");
|
11
|
+
|
12
|
+
template <class C> inline C *getPrivateData(VALUE self) {
|
13
|
+
C *c = static_cast<C *>(RTYPEDDATA_DATA(self));
|
14
|
+
if (!c) {
|
15
|
+
rb_raise(rb_eStandardError, "RTYPEDDATA_DATA for object missing data");
|
16
|
+
}
|
17
|
+
return c;
|
18
|
+
}
|
19
|
+
|
20
|
+
static inline void setPrivateData(VALUE self, void *p) {
|
21
|
+
RTYPEDDATA_DATA(self) = p;
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
#define GUARD_EXC(exp) \
|
26
|
+
{ \
|
27
|
+
try { \
|
28
|
+
exp \
|
29
|
+
} catch (std::exception &error) { \
|
30
|
+
rb_raise(rb_eFatal, "%s", error.what();) \
|
31
|
+
} \
|
32
|
+
}
|
33
|
+
|
34
|
+
template <rb_data_type_t *rbType> static VALUE classAllocate(VALUE klass) {
|
35
|
+
return rb_data_typed_object_wrap(klass, 0, rbType);
|
36
|
+
}
|
37
|
+
|
38
|
+
template <class C> static void freeInstance(void *inst) {
|
39
|
+
delete static_cast<C *>(inst);
|
40
|
+
}
|
41
|
+
|
42
|
+
#define DEF_TYPE_FLAGS 0
|
43
|
+
|
44
|
+
#define DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, Free, Typename) \
|
45
|
+
rb_data_type_t Typename = {Name, {0, Free, 0, 0, 0}, 0, 0, DEF_TYPE_FLAGS}
|
46
|
+
|
47
|
+
#define DEF_TYPE_CUSTOMTYPENAME(Klass, Typename) \
|
48
|
+
DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, #Klass, freeInstance<Klass>, Typename)
|
49
|
+
|
50
|
+
#define DEF_TYPE_CUSTOMNAME(Klass, Name) \
|
51
|
+
DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, freeInstance<Klass>, Klass##_rbType)
|
52
|
+
|
53
|
+
#define DEF_TYPE(Klass) DEF_TYPE_CUSTOMNAME(Klass, #Klass)
|
54
|
+
|
55
|
+
using namespace Rice;
|
56
|
+
|
57
|
+
#define DEF_METHOD_SET(klass, name, subclass) \
|
58
|
+
klass.define_method(#name, &rb_##subclass##_get_##name);
|
59
|
+
|
60
|
+
#define DEF_METHOD_GET(klass, name, subclass) \
|
61
|
+
klass.define_method(#name "=", &rb_##subclass##_set_##name);
|
62
|
+
|
63
|
+
#define DEF_METHOD_GET_SET(klass, name, subclass) \
|
64
|
+
klass.define_method(#name, &rb_##subclass##_get_##name); \
|
65
|
+
klass.define_method(#name "=", &rb_##subclass##_set_##name);
|
66
|
+
|
67
|
+
#define DEF_METHOD_EVENT(klass, name, subclass) \
|
68
|
+
klass.define_module_function("on_" #name "_connect", &rb_##subclass##_on_##name##_connect); \
|
69
|
+
klass.define_module_function("on_" #name "_disconect", &rb_##subclass##_on_##name##_disconnect);
|
70
|
+
|
71
|
+
#define LOG_ERROR_IF_STATE \
|
72
|
+
if (state) { \
|
73
|
+
/* callback function broke, theres not much we can do other than print out an error */ \
|
74
|
+
VALUE exception = rb_sprintf("[DiscordGameSDK] Callback function error: %" PRIsVALUE, rb_errinfo()); \
|
75
|
+
fwrite(StringValuePtr(exception), 1, RSTRING_LEN(exception), stderr); \
|
76
|
+
rb_set_errinfo(Qnil); \
|
77
|
+
}
|
78
|
+
|
79
|
+
VALUE rb_common_get_callback_proc(int args);
|
80
|
+
VALUE rb_common_get_event_proc(int args);
|
81
|
+
void rb_common_add_proc_to_hash(VALUE key, VALUE proc);
|
82
|
+
|
83
|
+
VALUE rb_result_to_obj(discord::Result);
|
84
|
+
extern VALUE rb_oPendingCallbacks;
|
85
|
+
extern VALUE rb_oProcEvents;
|
86
|
+
|
87
|
+
VALUE rb_discord_call_proc(VALUE ary);
|
88
|
+
std::function<void(discord::Result)> rb_discord_callback_wrapper_basic(VALUE proc);
|