Created
March 14, 2018 21:12
-
-
Save Exerosis/67389b682aa0f98e1dc2f417a1bfec4c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.mynt.backend.discord.responses.Token; | |
| import com.mynt.backend.discord.responses.User; | |
| import io.reactivex.Maybe; | |
| import retrofit2.http.*; | |
| import static com.mynt.backend.discord.Strings.*; | |
| public interface DiscordAPI { | |
| @GET(USERS) | |
| Maybe<User> users(@Header(HEADER_AUTHORIZATION) String token, @Path(PATH_USER) String user); | |
| @FormUrlEncoded | |
| @POST(TOKEN) | |
| Maybe<Token> token(@Field(FIELD_CLIENT_ID) String clientId, | |
| @Field(FIELD_CLIENT_SECRET) String clientSecret, | |
| @Field(FIELD_GRANT_TYPE) String grantType, | |
| @Field(FIELD_CODE) String code); | |
| default Maybe<Token> token(String code) { | |
| return token(CLIENT_ID, CLIENT_SECRET, GRANT_TYPE, code); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.google.gson.Gson; | |
| import com.google.gson.GsonBuilder; | |
| import com.mynt.backend.discord.responses.User; | |
| import io.reactivex.Observable; | |
| import io.reactivex.ObservableTransformer; | |
| import io.reactivex.disposables.Disposable; | |
| import io.reactivex.observables.ConnectableObservable; | |
| import okhttp3.OkHttpClient; | |
| import okhttp3.logging.HttpLoggingInterceptor; | |
| import org.apache.commons.io.IOUtils; | |
| import retrofit2.Retrofit; | |
| import retrofit2.converter.gson.GsonConverterFactory; | |
| import spark.Spark; | |
| import java.io.IOException; | |
| import java.net.URL; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| import java.util.UUID; | |
| import static com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES; | |
| import static com.mynt.backend.discord.Strings.*; | |
| import static io.reactivex.schedulers.Schedulers.io; | |
| import static java.lang.String.*; | |
| import static java.nio.charset.Charset.defaultCharset; | |
| import static retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.createWithScheduler; | |
| import static spark.Spark.port; | |
| public class DiscordConnection { | |
| private final ConnectableObservable<UUID> login; | |
| private final ConnectableObservable<UUID> home; | |
| private final ConnectableObservable<User> authenticated; | |
| private final List<Disposable> disposables = new ArrayList<>(); | |
| public DiscordConnection() { | |
| ServerAPI server = new ServerAPI(); | |
| Gson gson = new GsonBuilder() | |
| .setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES) | |
| .create(); | |
| HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); | |
| interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); | |
| OkHttpClient client = new OkHttpClient.Builder() | |
| .addInterceptor(interceptor) | |
| .build(); | |
| DiscordAPI discord = new Retrofit.Builder() | |
| .addConverterFactory(GsonConverterFactory.create(gson)) | |
| .addCallAdapterFactory(createWithScheduler(io())) | |
| .baseUrl(format(URL_DISCORD, "")) | |
| .client(client) | |
| .build() | |
| .create(DiscordAPI.class); | |
| login = server.login().compose(schedulers()).publish(); | |
| home = server.home().compose(schedulers()).publish(); | |
| authenticated = server.codes() | |
| .flatMapMaybe(code -> discord.token(code.getCode()) | |
| .flatMap(token -> discord.users(token.getTokenType() + " " + token.getAccessToken(), USER) | |
| .doOnSuccess(user -> user.setUuid(code.getUuid())) | |
| ) | |
| ).compose(schedulers()).publish(); | |
| } | |
| public Observable<User> onAuthenticated() { | |
| return authenticated; | |
| } | |
| public Observable<UUID> onHome() { | |
| return home; | |
| } | |
| public Observable<UUID> onLogin() { | |
| return login; | |
| } | |
| public String start(int port) { | |
| port(port); | |
| disposables.add(home.connect()); | |
| disposables.add(login.connect()); | |
| disposables.add(authenticated.connect()); | |
| try { | |
| return urlLocal(IOUtils.toString(new URL(URL_IP_CHECK), defaultCharset()).trim(), port, LOGIN); | |
| } catch (IOException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| public void stop() { | |
| Spark.stop(); | |
| disposables.forEach(Disposable::dispose); | |
| } | |
| private static <Type> ObservableTransformer<Type, Type> schedulers() { | |
| return upstream -> upstream; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import java.util.UUID; | |
| public class DiscordTest { | |
| public static void main(String[] args) throws InterruptedException { | |
| int port = 25565; | |
| DiscordConnection discord = new DiscordConnection(); | |
| String loginUrl = discord.start(port); | |
| System.out.println(loginUrl + "?uuid=" + UUID.randomUUID()); | |
| discord.onLogin().subscribe(System.out::println); | |
| discord.onHome().subscribe(System.out::println); | |
| discord.onAuthenticated().subscribe(user -> { | |
| System.out.println(); | |
| System.out.println("Authenticated user!"); | |
| System.out.println(user.getUsername() + "#" + user.getDiscriminator()); | |
| System.out.println(user.getEmail()); | |
| System.out.println(user.getUuid()); | |
| System.out.println(); | |
| }); | |
| Thread.sleep(100_000); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| import java.util.UUID; | |
| @Data | |
| public class Code { | |
| private final String code; | |
| private final UUID uuid; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| @Data | |
| public class Token { | |
| private final String accessToken; | |
| private final String tokenType; | |
| private final int expiresIn; | |
| private final String refreshToken; | |
| private final String scope; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| import java.util.UUID; | |
| @Data | |
| public class User { | |
| private final String username; | |
| private final String discriminator; | |
| private final String email; | |
| private final String avatar; | |
| private final boolean verified; | |
| private transient UUID uuid; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.mynt.backend.discord.responses.Code; | |
| import io.reactivex.Observable; | |
| import java.util.UUID; | |
| import static com.mynt.backend.discord.Strings.*; | |
| import static io.reactivex.Observable.*; | |
| import static java.lang.String.format; | |
| import static java.util.UUID.*; | |
| import static spark.Spark.*; | |
| public class ServerAPI { | |
| public Observable<Code> codes() { | |
| return create(observer -> get(CODES, (request, response) -> { | |
| String code = request.queryParams(PARAM_CODE); | |
| String state = request.queryParams(PARAM_STATE); | |
| if (code == null) | |
| return ERROR_CODE; | |
| if (state == null) | |
| return ERROR_STATE; | |
| observer.onNext(new Code(code, fromString(state))); | |
| return format(SCRIPT_REDIRECT, urlLocal(request.ip(), request.port(), format(STATE_HOME, state))); | |
| })); | |
| } | |
| public Observable<UUID> home() { | |
| return create(observer -> get(HOME, (request, response) -> { | |
| String uuid = request.queryParams(PARAM_UUID); | |
| if (uuid != null) | |
| observer.onNext(fromString(uuid)); | |
| return HOME_MESSAGE; | |
| })); | |
| } | |
| public Observable<UUID> login() { | |
| return create(observer -> get(LOGIN, (request, response) -> { | |
| String uuid = request.queryParams(PARAM_UUID); | |
| if (uuid == null) | |
| return ERROR_UUID; | |
| observer.onNext(fromString(uuid)); | |
| response.redirect(format(URL_AUTHORIZE, uuid, encode(urlLocal(request.ip(), request.port(), CODES)))); | |
| return response; | |
| })); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import java.io.UnsupportedEncodingException; | |
| import java.net.URLEncoder; | |
| import static java.lang.String.format; | |
| public class Strings { | |
| //--Misc-- | |
| static final String SCRIPT_REDIRECT = "<script>window.location.href = \"%s\";</script>"; | |
| static final String ENCODING = "UTF-8"; | |
| static final String GRANT_TYPE = "authorization_code"; | |
| static final String USER = "@me"; | |
| static final String HOME_MESSAGE = "Home :)"; | |
| static final String HEADER_AUTHORIZATION = "Authorization"; | |
| static final String PATH_USER = "user"; | |
| //--Client-- | |
| static final String CLIENT_ID = "374400233448275981"; | |
| static final String CLIENT_SECRET = "is9ZQgY_kgvJ_d6fbGhc2QsarSOeOXND"; | |
| //--URLs-- | |
| static final String URL_IP_CHECK = "http://checkip.amazonaws.com/"; | |
| static final String URL_LOCAL = "http://%s:%s/%s"; | |
| static final String URL_DISCORD = "https://discordapp.com/api/v6/%s"; | |
| static final String URL_AUTHORIZE; | |
| //--Paths-- | |
| static final String AUTHORIZE = "oauth2/authorize"; | |
| static final String USERS = "users/{" + PATH_USER + "}"; | |
| static final String TOKEN = "oauth2/token"; | |
| static final String CODES = "codes"; | |
| static final String HOME = "home"; | |
| static final String STATE_HOME = "home?uuid=%s"; | |
| static final String LOGIN = "login"; | |
| //--Params-- | |
| static final String PARAM_CODE = "code"; | |
| static final String PARAM_STATE = "state"; | |
| static final String PARAM_UUID = "uuid"; | |
| //--ERROR-- | |
| static final String ERROR_UUID = "Missing 'uuid' query param."; | |
| static final String ERROR_CODE = "Missing 'code' query param."; | |
| static final String ERROR_STATE = "Missing 'state' query param."; | |
| //--Fields-- | |
| static final String FIELD_CLIENT_ID = "client_id"; | |
| static final String FIELD_CLIENT_SECRET = "client_secret"; | |
| static final String FIELD_GRANT_TYPE = "grant_type"; | |
| static final String FIELD_CODE = "code"; | |
| static { | |
| URL_AUTHORIZE = format(URL_DISCORD, AUTHORIZE) + | |
| "?client_id=" + CLIENT_ID + | |
| "&response_type=code" + | |
| "&scope=email" + | |
| "&state=" + "%s" + | |
| "&redirect_uri=" + "%s"; | |
| } | |
| public static String urlLocal(String ip, int port, String path) { | |
| return format(URL_LOCAL, ip, port, path); | |
| } | |
| public static String encode(String url) { | |
| try { | |
| return URLEncoder.encode(url, ENCODING); | |
| } catch (UnsupportedEncodingException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.mynt.backend.discord.responses.Token; | |
| import com.mynt.backend.discord.responses.User; | |
| import io.reactivex.Maybe; | |
| import retrofit2.http.*; | |
| import static com.mynt.backend.discord.Strings.*; | |
| public interface DiscordAPI { | |
| @GET(USERS) | |
| Maybe<User> users(@Header(HEADER_AUTHORIZATION) String token, @Path(PATH_USER) String user); | |
| @FormUrlEncoded | |
| @POST(TOKEN) | |
| Maybe<Token> token(@Field(FIELD_CLIENT_ID) String clientId, | |
| @Field(FIELD_CLIENT_SECRET) String clientSecret, | |
| @Field(FIELD_GRANT_TYPE) String grantType, | |
| @Field(FIELD_CODE) String code); | |
| default Maybe<Token> token(String code) { | |
| return token(CLIENT_ID, CLIENT_SECRET, GRANT_TYPE, code); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.google.gson.Gson; | |
| import com.google.gson.GsonBuilder; | |
| import com.mynt.backend.discord.responses.User; | |
| import io.reactivex.Observable; | |
| import io.reactivex.ObservableTransformer; | |
| import io.reactivex.disposables.Disposable; | |
| import io.reactivex.observables.ConnectableObservable; | |
| import okhttp3.OkHttpClient; | |
| import okhttp3.logging.HttpLoggingInterceptor; | |
| import org.apache.commons.io.IOUtils; | |
| import retrofit2.Retrofit; | |
| import retrofit2.converter.gson.GsonConverterFactory; | |
| import spark.Spark; | |
| import java.io.IOException; | |
| import java.net.URL; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| import java.util.UUID; | |
| import static com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES; | |
| import static com.mynt.backend.discord.Strings.*; | |
| import static io.reactivex.schedulers.Schedulers.io; | |
| import static java.lang.String.*; | |
| import static java.nio.charset.Charset.defaultCharset; | |
| import static retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.createWithScheduler; | |
| import static spark.Spark.port; | |
| public class DiscordConnection { | |
| private final ConnectableObservable<UUID> login; | |
| private final ConnectableObservable<UUID> home; | |
| private final ConnectableObservable<User> authenticated; | |
| private final List<Disposable> disposables = new ArrayList<>(); | |
| public DiscordConnection() { | |
| ServerAPI server = new ServerAPI(); | |
| Gson gson = new GsonBuilder() | |
| .setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES) | |
| .create(); | |
| HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); | |
| interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); | |
| OkHttpClient client = new OkHttpClient.Builder() | |
| .addInterceptor(interceptor) | |
| .build(); | |
| DiscordAPI discord = new Retrofit.Builder() | |
| .addConverterFactory(GsonConverterFactory.create(gson)) | |
| .addCallAdapterFactory(createWithScheduler(io())) | |
| .baseUrl(format(URL_DISCORD, "")) | |
| .client(client) | |
| .build() | |
| .create(DiscordAPI.class); | |
| login = server.login().compose(schedulers()).publish(); | |
| home = server.home().compose(schedulers()).publish(); | |
| authenticated = server.codes() | |
| .flatMapMaybe(code -> discord.token(code.getCode()) | |
| .flatMap(token -> discord.users(token.getTokenType() + " " + token.getAccessToken(), USER) | |
| .doOnSuccess(user -> user.setUuid(code.getUuid())) | |
| ) | |
| ).compose(schedulers()).publish(); | |
| } | |
| public Observable<User> onAuthenticated() { | |
| return authenticated; | |
| } | |
| public Observable<UUID> onHome() { | |
| return home; | |
| } | |
| public Observable<UUID> onLogin() { | |
| return login; | |
| } | |
| public String start(int port) { | |
| port(port); | |
| disposables.add(home.connect()); | |
| disposables.add(login.connect()); | |
| disposables.add(authenticated.connect()); | |
| try { | |
| return urlLocal(IOUtils.toString(new URL(URL_IP_CHECK), defaultCharset()).trim(), port, LOGIN); | |
| } catch (IOException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| public void stop() { | |
| Spark.stop(); | |
| disposables.forEach(Disposable::dispose); | |
| } | |
| private static <Type> ObservableTransformer<Type, Type> schedulers() { | |
| return upstream -> upstream; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import java.util.UUID; | |
| public class DiscordTest { | |
| public static void main(String[] args) throws InterruptedException { | |
| int port = 25565; | |
| DiscordConnection discord = new DiscordConnection(); | |
| String loginUrl = discord.start(port); | |
| System.out.println(loginUrl + "?uuid=" + UUID.randomUUID()); | |
| discord.onLogin().subscribe(System.out::println); | |
| discord.onHome().subscribe(System.out::println); | |
| discord.onAuthenticated().subscribe(user -> { | |
| System.out.println(); | |
| System.out.println("Authenticated user!"); | |
| System.out.println(user.getUsername() + "#" + user.getDiscriminator()); | |
| System.out.println(user.getEmail()); | |
| System.out.println(user.getUuid()); | |
| System.out.println(); | |
| }); | |
| Thread.sleep(100_000); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| import java.util.UUID; | |
| @Data | |
| public class Code { | |
| private final String code; | |
| private final UUID uuid; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| @Data | |
| public class Token { | |
| private final String accessToken; | |
| private final String tokenType; | |
| private final int expiresIn; | |
| private final String refreshToken; | |
| private final String scope; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord.responses; | |
| import lombok.Data; | |
| import java.util.UUID; | |
| @Data | |
| public class User { | |
| private final String username; | |
| private final String discriminator; | |
| private final String email; | |
| private final String avatar; | |
| private final boolean verified; | |
| private transient UUID uuid; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import com.mynt.backend.discord.responses.Code; | |
| import io.reactivex.Observable; | |
| import java.util.UUID; | |
| import static com.mynt.backend.discord.Strings.*; | |
| import static io.reactivex.Observable.*; | |
| import static java.lang.String.format; | |
| import static java.util.UUID.*; | |
| import static spark.Spark.*; | |
| public class ServerAPI { | |
| public Observable<Code> codes() { | |
| return create(observer -> get(CODES, (request, response) -> { | |
| String code = request.queryParams(PARAM_CODE); | |
| String state = request.queryParams(PARAM_STATE); | |
| if (code == null) | |
| return ERROR_CODE; | |
| if (state == null) | |
| return ERROR_STATE; | |
| observer.onNext(new Code(code, fromString(state))); | |
| return format(SCRIPT_REDIRECT, urlLocal(request.ip(), request.port(), format(STATE_HOME, state))); | |
| })); | |
| } | |
| public Observable<UUID> home() { | |
| return create(observer -> get(HOME, (request, response) -> { | |
| String uuid = request.queryParams(PARAM_UUID); | |
| if (uuid != null) | |
| observer.onNext(fromString(uuid)); | |
| return HOME_MESSAGE; | |
| })); | |
| } | |
| public Observable<UUID> login() { | |
| return create(observer -> get(LOGIN, (request, response) -> { | |
| String uuid = request.queryParams(PARAM_UUID); | |
| if (uuid == null) | |
| return ERROR_UUID; | |
| observer.onNext(fromString(uuid)); | |
| response.redirect(format(URL_AUTHORIZE, uuid, encode(urlLocal(request.ip(), request.port(), CODES)))); | |
| return response; | |
| })); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.mynt.backend.discord; | |
| import java.io.UnsupportedEncodingException; | |
| import java.net.URLEncoder; | |
| import static java.lang.String.format; | |
| public class Strings { | |
| //--Misc-- | |
| static final String SCRIPT_REDIRECT = "<script>window.location.href = \"%s\";</script>"; | |
| static final String ENCODING = "UTF-8"; | |
| static final String GRANT_TYPE = "authorization_code"; | |
| static final String USER = "@me"; | |
| static final String HOME_MESSAGE = "Home :)"; | |
| static final String HEADER_AUTHORIZATION = "Authorization"; | |
| static final String PATH_USER = "user"; | |
| //--Client-- | |
| static final String CLIENT_ID = "374400233448275981"; | |
| static final String CLIENT_SECRET = "is9ZQgY_kgvJ_d6fbGhc2QsarSOeOXND"; | |
| //--URLs-- | |
| static final String URL_IP_CHECK = "http://checkip.amazonaws.com/"; | |
| static final String URL_LOCAL = "http://%s:%s/%s"; | |
| static final String URL_DISCORD = "https://discordapp.com/api/v6/%s"; | |
| static final String URL_AUTHORIZE; | |
| //--Paths-- | |
| static final String AUTHORIZE = "oauth2/authorize"; | |
| static final String USERS = "users/{" + PATH_USER + "}"; | |
| static final String TOKEN = "oauth2/token"; | |
| static final String CODES = "codes"; | |
| static final String HOME = "home"; | |
| static final String STATE_HOME = "home?uuid=%s"; | |
| static final String LOGIN = "login"; | |
| //--Params-- | |
| static final String PARAM_CODE = "code"; | |
| static final String PARAM_STATE = "state"; | |
| static final String PARAM_UUID = "uuid"; | |
| //--ERROR-- | |
| static final String ERROR_UUID = "Missing 'uuid' query param."; | |
| static final String ERROR_CODE = "Missing 'code' query param."; | |
| static final String ERROR_STATE = "Missing 'state' query param."; | |
| //--Fields-- | |
| static final String FIELD_CLIENT_ID = "client_id"; | |
| static final String FIELD_CLIENT_SECRET = "client_secret"; | |
| static final String FIELD_GRANT_TYPE = "grant_type"; | |
| static final String FIELD_CODE = "code"; | |
| static { | |
| URL_AUTHORIZE = format(URL_DISCORD, AUTHORIZE) + | |
| "?client_id=" + CLIENT_ID + | |
| "&response_type=code" + | |
| "&scope=email" + | |
| "&state=" + "%s" + | |
| "&redirect_uri=" + "%s"; | |
| } | |
| public static String urlLocal(String ip, int port, String path) { | |
| return format(URL_LOCAL, ip, port, path); | |
| } | |
| public static String encode(String url) { | |
| try { | |
| return URLEncoder.encode(url, ENCODING); | |
| } catch (UnsupportedEncodingException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment