Remove http-api and http-service
These are being split into a separate repository at https://github.com/runelite/api.runelite.net
This commit is contained in:
@@ -8,8 +8,6 @@ If you have any questions, please join our IRC channel on [irc.rizon.net #runeli
|
||||
## Project Layout
|
||||
|
||||
- [cache](cache/src/main/java/net/runelite/cache) - Libraries used for reading/writing cache files, as well as the data in it
|
||||
- [http-api](http-api/src/main/java/net/runelite/http/api) - API for api.runelite.net
|
||||
- [http-service](http-service/src/main/java/net/runelite/http/service) - Service for api.runelite.net
|
||||
- [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client
|
||||
- [runelite-client](runelite-client/src/main/java/net/runelite/client) - Game client with plugins
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.8.8-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Web API</name>
|
||||
<artifactId>http-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
<version>3.14.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.awt.Color;
|
||||
import java.time.Instant;
|
||||
import net.runelite.http.api.gson.ColorTypeAdapter;
|
||||
import net.runelite.http.api.gson.IllegalReflectionExclusion;
|
||||
import net.runelite.http.api.gson.InstantTypeAdapter;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class RuneLiteAPI
|
||||
{
|
||||
public static final String RUNELITE_AUTH = "RUNELITE-AUTH";
|
||||
public static final String RUNELITE_MACHINEID = "RUNELITE-MACHINEID";
|
||||
|
||||
@Deprecated
|
||||
public static OkHttpClient CLIENT;
|
||||
public static final Gson GSON;
|
||||
public static final MediaType JSON = MediaType.parse("application/json");
|
||||
|
||||
static
|
||||
{
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
|
||||
gsonBuilder
|
||||
.registerTypeAdapter(Instant.class, new InstantTypeAdapter())
|
||||
.registerTypeAdapter(Color.class, new ColorTypeAdapter());
|
||||
|
||||
boolean assertionsEnabled = false;
|
||||
assert assertionsEnabled = true;
|
||||
if (assertionsEnabled)
|
||||
{
|
||||
IllegalReflectionExclusion jbe = new IllegalReflectionExclusion();
|
||||
gsonBuilder.addSerializationExclusionStrategy(jbe);
|
||||
gsonBuilder.addDeserializationExclusionStrategy(jbe);
|
||||
}
|
||||
|
||||
GSON = gsonBuilder.create();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.account;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OAuthResponse
|
||||
{
|
||||
private String oauthUrl;
|
||||
private UUID uid;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.chat;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Duels
|
||||
{
|
||||
private int wins;
|
||||
private int losses;
|
||||
private int winningStreak;
|
||||
private int losingStreak;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.chat;
|
||||
|
||||
public enum LayoutRoom
|
||||
{
|
||||
START,
|
||||
END,
|
||||
SCAVENGERS,
|
||||
FARMING,
|
||||
EMPTY,
|
||||
|
||||
TEKTON,
|
||||
MUTTADILES,
|
||||
GUARDIANS,
|
||||
VESPULA,
|
||||
SHAMANS,
|
||||
VASA,
|
||||
VANGUARDS,
|
||||
MYSTICS,
|
||||
UNKNOWN_COMBAT,
|
||||
|
||||
CRABS,
|
||||
ICE_DEMON,
|
||||
TIGHTROPE,
|
||||
THIEVING,
|
||||
UNKNOWN_PUZZLE;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.chat;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Task
|
||||
{
|
||||
private String task;
|
||||
private int amount;
|
||||
private int initialAmount;
|
||||
private String location;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ConfigEntry
|
||||
{
|
||||
private String key;
|
||||
private String value;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Configuration
|
||||
{
|
||||
private List<ConfigEntry> config = new ArrayList<>();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.feed;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FeedItem
|
||||
{
|
||||
private final FeedItemType type;
|
||||
private String avatar;
|
||||
private final String title;
|
||||
private final String content;
|
||||
private final String url;
|
||||
private final long timestamp;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.feed;
|
||||
|
||||
public enum FeedItemType
|
||||
{
|
||||
BLOG_POST,
|
||||
TWEET,
|
||||
OSRS_NEWS
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.feed;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class FeedResult
|
||||
{
|
||||
private List<FeedItem> items;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ge;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.worlds.WorldType;
|
||||
|
||||
@Data
|
||||
public class GrandExchangeTrade
|
||||
{
|
||||
private boolean buy;
|
||||
private boolean cancel;
|
||||
private boolean login;
|
||||
private int itemId;
|
||||
private int qty;
|
||||
private int dqty;
|
||||
private int total;
|
||||
private int spent;
|
||||
private int dspent;
|
||||
private int offer;
|
||||
private int slot;
|
||||
private WorldType worldType;
|
||||
private int seq;
|
||||
private Instant resetTime;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.gson;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ColorTypeAdapter extends TypeAdapter<Color>
|
||||
{
|
||||
@Override
|
||||
public void write(JsonWriter out, Color value) throws IOException
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
int rgba = value.getRGB();
|
||||
out.value(String.format("#%08X", rgba));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color read(JsonReader in) throws IOException
|
||||
{
|
||||
switch (in.peek())
|
||||
{
|
||||
case NULL:
|
||||
in.nextNull();
|
||||
return null;
|
||||
case STRING:
|
||||
{
|
||||
String value = in.nextString();
|
||||
if (value.charAt(0) == '#')
|
||||
{
|
||||
value = value.substring(1);
|
||||
}
|
||||
int intValue = Integer.parseUnsignedInt(value, 16);
|
||||
return new Color(intValue, true);
|
||||
}
|
||||
case BEGIN_OBJECT:
|
||||
{
|
||||
in.beginObject();
|
||||
double value = 0;
|
||||
while (in.peek() != JsonToken.END_OBJECT)
|
||||
{
|
||||
switch (in.nextName())
|
||||
{
|
||||
case "value":
|
||||
value = in.nextDouble();
|
||||
break;
|
||||
default:
|
||||
in.skipValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
in.endObject();
|
||||
return new Color((int) value, true);
|
||||
}
|
||||
}
|
||||
return null; // throws
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.gson;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class IllegalReflectionExclusion implements ExclusionStrategy
|
||||
{
|
||||
private static final Set<ClassLoader> PRIVATE_CLASSLOADERS = new HashSet<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (ClassLoader cl = ClassLoader.getSystemClassLoader(); cl != null; )
|
||||
{
|
||||
cl = cl.getParent();
|
||||
PRIVATE_CLASSLOADERS.add(cl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f)
|
||||
{
|
||||
if (!PRIVATE_CLASSLOADERS.contains(f.getDeclaringClass().getClassLoader()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
assert !Modifier.isPrivate(f.getDeclaringClass().getModifiers()) : "gsoning private class " + f.getDeclaringClass().getName();
|
||||
try
|
||||
{
|
||||
f.getDeclaringClass().getField(f.getName());
|
||||
}
|
||||
catch (NoSuchFieldException e)
|
||||
{
|
||||
throw new AssertionError("gsoning private field " + f.getDeclaringClass() + "." + f.getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.gson;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
|
||||
// Just add water!
|
||||
public class InstantTypeAdapter extends TypeAdapter<Instant>
|
||||
{
|
||||
@Override
|
||||
public void write(JsonWriter out, Instant value) throws IOException
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
out.value(value.toEpochMilli());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant read(JsonReader in) throws IOException
|
||||
{
|
||||
if (in.peek() == JsonToken.NULL)
|
||||
{
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (in.peek() == JsonToken.NUMBER)
|
||||
{
|
||||
long jsTime = in.nextLong();
|
||||
return Instant.ofEpochMilli(jsTime);
|
||||
}
|
||||
|
||||
long seconds = 0;
|
||||
int nanos = 0;
|
||||
in.beginObject();
|
||||
while (in.peek() != JsonToken.END_OBJECT)
|
||||
{
|
||||
switch (in.nextName())
|
||||
{
|
||||
case "nanos":
|
||||
nanos = in.nextInt();
|
||||
break;
|
||||
case "seconds":
|
||||
seconds = in.nextLong();
|
||||
break;
|
||||
}
|
||||
}
|
||||
in.endObject();
|
||||
|
||||
return Instant.ofEpochSecond(seconds, nanos);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.item;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@Builder
|
||||
public class ItemEquipmentStats
|
||||
{
|
||||
private int slot;
|
||||
|
||||
@SerializedName("is2h")
|
||||
private boolean isTwoHanded;
|
||||
|
||||
private int astab;
|
||||
private int aslash;
|
||||
private int acrush;
|
||||
private int amagic;
|
||||
private int arange;
|
||||
|
||||
private int dstab;
|
||||
private int dslash;
|
||||
private int dcrush;
|
||||
private int dmagic;
|
||||
private int drange;
|
||||
|
||||
private int str;
|
||||
private int rstr;
|
||||
private int mdmg;
|
||||
private int prayer;
|
||||
private int aspeed;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.item;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ItemPrice
|
||||
{
|
||||
private int id;
|
||||
private String name;
|
||||
private int price;
|
||||
private int wikiPrice;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.item;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class ItemStats
|
||||
{
|
||||
private boolean equipable;
|
||||
private double weight;
|
||||
@SerializedName("ge_limit")
|
||||
private int geLimit;
|
||||
|
||||
private ItemEquipmentStats equipment;
|
||||
|
||||
public ItemStats subtract(ItemStats other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
final double newWeight = weight - other.weight;
|
||||
final ItemEquipmentStats newEquipment;
|
||||
|
||||
|
||||
if (other.equipment != null)
|
||||
{
|
||||
final ItemEquipmentStats equipment = this.equipment != null
|
||||
? this.equipment
|
||||
: new ItemEquipmentStats.ItemEquipmentStatsBuilder().build();
|
||||
|
||||
newEquipment = new ItemEquipmentStats.ItemEquipmentStatsBuilder()
|
||||
.slot(equipment.getSlot())
|
||||
.astab(equipment.getAstab() - other.equipment.getAstab())
|
||||
.aslash(equipment.getAslash() - other.equipment.getAslash())
|
||||
.acrush(equipment.getAcrush() - other.equipment.getAcrush())
|
||||
.amagic(equipment.getAmagic() - other.equipment.getAmagic())
|
||||
.arange(equipment.getArange() - other.equipment.getArange())
|
||||
.dstab(equipment.getDstab() - other.equipment.getDstab())
|
||||
.dslash(equipment.getDslash() - other.equipment.getDslash())
|
||||
.dcrush(equipment.getDcrush() - other.equipment.getDcrush())
|
||||
.dmagic(equipment.getDmagic() - other.equipment.getDmagic())
|
||||
.drange(equipment.getDrange() - other.equipment.getDrange())
|
||||
.str(equipment.getStr() - other.equipment.getStr())
|
||||
.rstr(equipment.getRstr() - other.equipment.getRstr())
|
||||
.mdmg(equipment.getMdmg() - other.equipment.getMdmg())
|
||||
.prayer(equipment.getPrayer() - other.equipment.getPrayer())
|
||||
.aspeed(equipment.getAspeed() - other.equipment.getAspeed())
|
||||
.build();
|
||||
}
|
||||
else
|
||||
{
|
||||
newEquipment = equipment;
|
||||
}
|
||||
|
||||
return new ItemStats(equipable, newWeight, 0, newEquipment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.item;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public enum ItemType
|
||||
{
|
||||
DEFAULT;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ItemType.class);
|
||||
|
||||
public static ItemType of(String type)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ItemType.valueOf(type.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
logger.warn("unable to convert type", ex);
|
||||
return DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.loottracker;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GameItem
|
||||
{
|
||||
private int id;
|
||||
private int qty;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.loottracker;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LootAggregate
|
||||
{
|
||||
private String eventId;
|
||||
private LootRecordType type;
|
||||
private Collection<GameItem> drops;
|
||||
private Instant first_time;
|
||||
private Instant last_time;
|
||||
private int amount;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.loottracker;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LootRecord
|
||||
{
|
||||
private String eventId;
|
||||
private LootRecordType type;
|
||||
private Object metadata;
|
||||
private Collection<GameItem> drops;
|
||||
private Instant time;
|
||||
private Integer world;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.loottracker;
|
||||
|
||||
public enum LootRecordType
|
||||
{
|
||||
NPC,
|
||||
PLAYER,
|
||||
EVENT,
|
||||
PICKPOCKET,
|
||||
UNKNOWN
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.worlds;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@Builder
|
||||
public class World
|
||||
{
|
||||
private int id;
|
||||
private EnumSet<WorldType> types;
|
||||
private String address;
|
||||
private String activity;
|
||||
private int location;
|
||||
private int players;
|
||||
|
||||
public WorldRegion getRegion()
|
||||
{
|
||||
return WorldRegion.valueOf(location);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, melky <https://github.com/melkypie>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.worlds;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Holds the data for each world's region (location)
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WorldRegion
|
||||
{
|
||||
UNITED_STATES_OF_AMERICA("US", "USA"),
|
||||
UNITED_KINGDOM("GB", "GBR"),
|
||||
AUSTRALIA("AU", "AUS"),
|
||||
GERMANY("DE", "DEU");
|
||||
|
||||
/**
|
||||
* ISO-3166-1 alpha-2 country code
|
||||
*/
|
||||
private final String alpha2;
|
||||
/**
|
||||
* ISO-3166-1 alpha-3 country code
|
||||
*/
|
||||
private final String alpha3;
|
||||
|
||||
/**
|
||||
* Gets the region using the location id
|
||||
* {@link WorldRegion} value.
|
||||
*
|
||||
* @param locationId the location id of world
|
||||
* @return WorldRegion the region of the world
|
||||
*/
|
||||
public static WorldRegion valueOf(int locationId)
|
||||
{
|
||||
switch (locationId)
|
||||
{
|
||||
case 0:
|
||||
return UNITED_STATES_OF_AMERICA;
|
||||
case 1:
|
||||
return UNITED_KINGDOM;
|
||||
case 3:
|
||||
return AUSTRALIA;
|
||||
case 7:
|
||||
return GERMANY;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.worlds;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorldResult
|
||||
{
|
||||
private List<World> worlds;
|
||||
|
||||
public List<World> getWorlds()
|
||||
{
|
||||
return worlds;
|
||||
}
|
||||
|
||||
public void setWorlds(List<World> worlds)
|
||||
{
|
||||
this.worlds = worlds;
|
||||
}
|
||||
|
||||
public World findWorld(int worldNum)
|
||||
{
|
||||
for (World world : worlds)
|
||||
{
|
||||
if (world.getId() == worldNum)
|
||||
{
|
||||
return world;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.worlds;
|
||||
|
||||
public enum WorldType
|
||||
{
|
||||
MEMBERS,
|
||||
PVP,
|
||||
BOUNTY,
|
||||
SKILL_TOTAL,
|
||||
HIGH_RISK,
|
||||
LAST_MAN_STANDING,
|
||||
NOSAVE_MODE,
|
||||
DEADMAN,
|
||||
TOURNAMENT,
|
||||
SEASONAL;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.runelite.http.api.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Adapts values whose runtime type may differ from their declaration type. This
|
||||
* is necessary when a field's type is not the same type that GSON should create
|
||||
* when deserializing that field. For example, consider these types:
|
||||
* <pre> {@code
|
||||
* abstract class Shape {
|
||||
* int x;
|
||||
* int y;
|
||||
* }
|
||||
* class Circle extends Shape {
|
||||
* int radius;
|
||||
* }
|
||||
* class Rectangle extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Diamond extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Drawing {
|
||||
* Shape bottomShape;
|
||||
* Shape topShape;
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>Without additional type information, the serialized JSON is ambiguous. Is
|
||||
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* This class addresses this problem by adding type information to the
|
||||
* serialized JSON and honoring that type information when the JSON is
|
||||
* deserialized: <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "type": "Diamond",
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "type": "Circle",
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* Both the type field name ({@code "type"}) and the type labels ({@code
|
||||
* "Rectangle"}) are configurable.
|
||||
*
|
||||
* <h3>Registering Types</h3>
|
||||
* Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
|
||||
* name to the {@link #of} factory method. If you don't supply an explicit type
|
||||
* field name, {@code "type"} will be used. <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
|
||||
* = RuntimeTypeAdapterFactory.of(Shape.class, "type");
|
||||
* }</pre>
|
||||
* Next register all of your subtypes. Every subtype must be explicitly
|
||||
* registered. This protects your application from injection attacks. If you
|
||||
* don't supply an explicit type label, the type's simple name will be used.
|
||||
* <pre> {@code
|
||||
* shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
|
||||
* shapeAdapter.registerSubtype(Circle.class, "Circle");
|
||||
* shapeAdapter.registerSubtype(Diamond.class, "Diamond");
|
||||
* }</pre>
|
||||
* Finally, register the type adapter factory in your application's GSON builder:
|
||||
* <pre> {@code
|
||||
* Gson gson = new GsonBuilder()
|
||||
* .registerTypeAdapterFactory(shapeAdapterFactory)
|
||||
* .create();
|
||||
* }</pre>
|
||||
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
|
||||
* .registerSubtype(Rectangle.class)
|
||||
* .registerSubtype(Circle.class)
|
||||
* .registerSubtype(Diamond.class);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
|
||||
private final Class<?> baseType;
|
||||
private final String typeFieldName;
|
||||
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<String, Class<?>>();
|
||||
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<Class<?>, String>();
|
||||
|
||||
private RuntimeTypeAdapterFactory(Class<?> baseType, String typeFieldName) {
|
||||
if (typeFieldName == null || baseType == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.baseType = baseType;
|
||||
this.typeFieldName = typeFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
|
||||
return new RuntimeTypeAdapterFactory<T>(baseType, typeFieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
|
||||
* the type field name.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
|
||||
return new RuntimeTypeAdapterFactory<T>(baseType, "type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by {@code label}. Labels are case
|
||||
* sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or {@code label}
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
|
||||
if (type == null || label == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
|
||||
throw new IllegalArgumentException("types and labels must be unique");
|
||||
}
|
||||
labelToSubtype.put(label, type);
|
||||
subtypeToLabel.put(type, label);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by its {@link Class#getSimpleName simple
|
||||
* name}. Labels are case sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or its simple name
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
|
||||
return registerSubtype(type, type.getSimpleName());
|
||||
}
|
||||
|
||||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
|
||||
if (type.getRawType() != baseType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, TypeAdapter<?>> labelToDelegate
|
||||
= new LinkedHashMap<String, TypeAdapter<?>>();
|
||||
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
|
||||
= new LinkedHashMap<Class<?>, TypeAdapter<?>>();
|
||||
for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
|
||||
TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
|
||||
labelToDelegate.put(entry.getKey(), delegate);
|
||||
subtypeToDelegate.put(entry.getValue(), delegate);
|
||||
}
|
||||
|
||||
return new TypeAdapter<R>() {
|
||||
@Override public R read(JsonReader in) throws IOException {
|
||||
JsonElement jsonElement = Streams.parse(in);
|
||||
JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
|
||||
if (labelJsonElement == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType
|
||||
+ " because it does not define a field named " + typeFieldName);
|
||||
}
|
||||
String label = labelJsonElement.getAsString();
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
|
||||
+ label + "; did you forget to register a subtype?");
|
||||
}
|
||||
return delegate.fromJsonTree(jsonElement);
|
||||
}
|
||||
|
||||
@Override public void write(JsonWriter out, R value) throws IOException {
|
||||
Class<?> srcType = value.getClass();
|
||||
String label = subtypeToLabel.get(srcType);
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ "; did you forget to register a subtype?");
|
||||
}
|
||||
JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
|
||||
if (jsonObject.has(typeFieldName)) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ " because it already defines a field named " + typeFieldName);
|
||||
}
|
||||
JsonObject clone = new JsonObject();
|
||||
clone.add(typeFieldName, new JsonPrimitive(label));
|
||||
for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
|
||||
clone.add(e.getKey(), e.getValue());
|
||||
}
|
||||
Streams.write(clone, out);
|
||||
}
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.ws.messages.Handshake;
|
||||
import net.runelite.http.api.ws.messages.LoginResponse;
|
||||
import net.runelite.http.api.ws.messages.party.Join;
|
||||
import net.runelite.http.api.ws.messages.party.Part;
|
||||
import net.runelite.http.api.ws.messages.party.PartyChatMessage;
|
||||
import net.runelite.http.api.ws.messages.party.UserJoin;
|
||||
import net.runelite.http.api.ws.messages.party.UserPart;
|
||||
import net.runelite.http.api.ws.messages.party.UserSync;
|
||||
|
||||
public class WebsocketGsonFactory
|
||||
{
|
||||
private static final Collection<Class<? extends WebsocketMessage>> MESSAGES;
|
||||
|
||||
static
|
||||
{
|
||||
final List<Class<? extends WebsocketMessage>> messages = new ArrayList<>();
|
||||
messages.add(Handshake.class);
|
||||
messages.add(LoginResponse.class);
|
||||
messages.add(Join.class);
|
||||
messages.add(Part.class);
|
||||
messages.add(UserJoin.class);
|
||||
messages.add(UserPart.class);
|
||||
messages.add(UserSync.class);
|
||||
messages.add(PartyChatMessage.class);
|
||||
MESSAGES = messages;
|
||||
}
|
||||
|
||||
public static RuntimeTypeAdapterFactory<WebsocketMessage> factory(final Collection<Class<? extends WebsocketMessage>> messages)
|
||||
{
|
||||
final RuntimeTypeAdapterFactory<WebsocketMessage> factory = RuntimeTypeAdapterFactory.of(WebsocketMessage.class);
|
||||
|
||||
for (Class<? extends WebsocketMessage> message : MESSAGES)
|
||||
{
|
||||
factory.registerSubtype(message);
|
||||
}
|
||||
|
||||
for (Class<? extends WebsocketMessage> message : messages)
|
||||
{
|
||||
factory.registerSubtype(message);
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
public static Gson build(final RuntimeTypeAdapterFactory<WebsocketMessage> factory)
|
||||
{
|
||||
return RuneLiteAPI.GSON.newBuilder()
|
||||
.registerTypeAdapterFactory(factory)
|
||||
.create();
|
||||
}
|
||||
|
||||
public static Gson build()
|
||||
{
|
||||
return build(factory(Collections.emptyList()));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws;
|
||||
|
||||
public class WebsocketMessage
|
||||
{
|
||||
protected boolean _party;
|
||||
|
||||
public boolean isParty()
|
||||
{
|
||||
return _party;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
@Data
|
||||
public class Handshake extends WebsocketMessage
|
||||
{
|
||||
private UUID session;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
/**
|
||||
* Called after a successful login to the server
|
||||
*/
|
||||
@Data
|
||||
public class LoginResponse extends WebsocketMessage
|
||||
{
|
||||
private String username;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Join extends WebsocketMessage
|
||||
{
|
||||
private final UUID partyId;
|
||||
private final String name;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
public class Part extends WebsocketMessage
|
||||
{
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class PartyChatMessage extends PartyMemberMessage
|
||||
{
|
||||
private final String value;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class PartyMemberMessage extends PartyMessage
|
||||
{
|
||||
private UUID memberId;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
public abstract class PartyMessage extends WebsocketMessage
|
||||
{
|
||||
public PartyMessage()
|
||||
{
|
||||
_party = true;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserJoin extends WebsocketMessage
|
||||
{
|
||||
private final UUID memberId;
|
||||
private final UUID partyId;
|
||||
private final String name;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserPart extends WebsocketMessage
|
||||
{
|
||||
private final UUID memberId;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ws.messages.party;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserSync extends PartyMemberMessage
|
||||
{
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.xtea;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class XteaKey
|
||||
{
|
||||
private int region;
|
||||
private int keys[];
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.xtea;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class XteaRequest
|
||||
{
|
||||
private int revision;
|
||||
private List<XteaKey> keys = new ArrayList<>();
|
||||
|
||||
public void addKey(XteaKey key)
|
||||
{
|
||||
keys.add(key);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.gson;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ColorTypeAdapterTest
|
||||
{
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
test("null", null, true);
|
||||
test("{\"value\":-13347208,\"falpha\":0.0}", new Color(0x12345678, false), false);
|
||||
test("{\"value\":305419896,\"falpha\":0.0}", new Color(0x12345678, true), false);
|
||||
test("{\"value\":-1.4221317E7,\"falpha\":0.0}", new Color(0xFF26FFFB, true), false);
|
||||
test("\"#FF345678\"", new Color(0x12345678, false), true);
|
||||
test("\"#12345678\"", new Color(0x12345678, true), true);
|
||||
test("\"#FF26FFFB\"", new Color(0xFF26FFFB, true), true);
|
||||
}
|
||||
|
||||
private void test(String json, Color object, boolean exactEncoding)
|
||||
{
|
||||
Color parsed = RuneLiteAPI.GSON.fromJson(json, Color.class);
|
||||
Assert.assertEquals(object, parsed);
|
||||
String serialized = RuneLiteAPI.GSON.toJson(object);
|
||||
if (exactEncoding)
|
||||
{
|
||||
Assert.assertEquals(json, serialized);
|
||||
}
|
||||
Color roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Color.class);
|
||||
Assert.assertEquals(object, roundTripped);
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.gson;
|
||||
|
||||
import java.time.Instant;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class InstantTypeAdapterTest
|
||||
{
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
test("null", null, true);
|
||||
test("{\"seconds\":1609538310,\"nanos\":291000000}", Instant.ofEpochSecond(1609538310, 291_000_000), false);
|
||||
test("1609538310291", Instant.ofEpochSecond(1609538310, 291_000_000), true);
|
||||
}
|
||||
|
||||
private void test(String json, Instant object, boolean exactEncoding)
|
||||
{
|
||||
Instant parsed = RuneLiteAPI.GSON.fromJson(json, Instant.class);
|
||||
Assert.assertEquals(object, parsed);
|
||||
String serialized = RuneLiteAPI.GSON.toJson(object);
|
||||
if (exactEncoding)
|
||||
{
|
||||
Assert.assertEquals(json, serialized);
|
||||
}
|
||||
Instant roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Instant.class);
|
||||
Assert.assertEquals(object, roundTripped);
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.8.8-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Web Service</name>
|
||||
<artifactId>http-service</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>
|
||||
<git.commit.id.abbrev>nogit</git.commit.id.abbrev>
|
||||
<git.dirty>false</git.dirty>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>http-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>cache</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>2.2.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sql2o</groupId>
|
||||
<artifactId>sql2o</artifactId>
|
||||
<version>1.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-apis</artifactId>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>3.0.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>3.10.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
<version>3.14.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<finalName>runelite-${project.version}</finalName>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<configuration>
|
||||
<!-- Prevent reloading resources since it doesn't work when the resources are also filtered -->
|
||||
<addResources>false</addResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.kongchen</groupId>
|
||||
<artifactId>swagger-maven-plugin</artifactId>
|
||||
<version>3.1.8</version>
|
||||
<dependencies>
|
||||
<!-- Java 11+ does not include this anymore -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<apiSources>
|
||||
<apiSource>
|
||||
<springmvc>true</springmvc>
|
||||
<locations>
|
||||
<location>net.runelite</location>
|
||||
</locations>
|
||||
<schemes>
|
||||
<scheme>https</scheme>
|
||||
</schemes>
|
||||
<host>api.runelite.net</host>
|
||||
<basePath>/runelite-${project.version}</basePath>
|
||||
<info>
|
||||
<title>${project.parent.name} HTTP API</title>
|
||||
<version>${project.version}</version>
|
||||
<description>${project.description}</description>
|
||||
<license>
|
||||
<url>https://tldrlegal.com/license/bsd-2-clause-license-(freebsd)</url>
|
||||
<name>BSD 2-Clause "Simplified"</name>
|
||||
</license>
|
||||
</info>
|
||||
<templatePath>${basedir}/src/main/templates/template.html.hbs</templatePath>
|
||||
<swaggerDirectory>${project.build.directory}/swagger-ui</swaggerDirectory>
|
||||
<outputPath>${project.build.directory}/site/api.html</outputPath>
|
||||
<attachSwaggerArtifact>true</attachSwaggerArtifact>
|
||||
<outputFormats>json</outputFormats>
|
||||
</apiSource>
|
||||
</apiSources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
<version>2.2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>query-git-info</id>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
||||
<failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
|
||||
<gitDescribe>
|
||||
<skip>true</skip>
|
||||
</gitDescribe>
|
||||
<includeOnlyProperties>
|
||||
<includeOnlyProperty>git.commit.id.abbrev</includeOnlyProperty>
|
||||
<includeOnlyProperty>git.dirty</includeOnlyProperty>
|
||||
</includeOnlyProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Automatic expansion of properties in configuration https://docs.spring.io/spring-boot/docs/2.0.0.M7/reference/html/howto-properties-and-configuration.html#howto-automatic-expansion-maven -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<configuration>
|
||||
<delimiters>
|
||||
<delimiter>@</delimiter>
|
||||
</delimiters>
|
||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import com.google.common.base.Strings;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.naming.NamingException;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.sql.DataSource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.service.util.InstantConverter;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.impl.StaticLoggerBinder;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
|
||||
import org.springframework.jndi.JndiTemplate;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.sql2o.Sql2o;
|
||||
import org.sql2o.converters.Converter;
|
||||
import org.sql2o.quirks.NoQuirks;
|
||||
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
public class SpringBootWebApplication extends SpringBootServletInitializer
|
||||
{
|
||||
@Bean
|
||||
protected ServletContextListener listener(OkHttpClient client)
|
||||
{
|
||||
return new ServletContextListener()
|
||||
{
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
log.info("RuneLite API started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
// Destroy okhttp client
|
||||
client.dispatcher().executorService().shutdown();
|
||||
client.connectionPool().evictAll();
|
||||
try
|
||||
{
|
||||
Cache cache = client.cache();
|
||||
if (cache != null)
|
||||
{
|
||||
cache.close();
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn(null, ex);
|
||||
}
|
||||
|
||||
log.info("RuneLite API stopped");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "datasource.runelite")
|
||||
@Bean("dataSourceRuneLite")
|
||||
public DataSourceProperties dataSourceProperties()
|
||||
{
|
||||
return new DataSourceProperties();
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "datasource.runelite-cache")
|
||||
@Bean("dataSourceRuneLiteCache")
|
||||
public DataSourceProperties dataSourcePropertiesCache()
|
||||
{
|
||||
return new DataSourceProperties();
|
||||
}
|
||||
|
||||
@Bean(value = "runelite", destroyMethod = "")
|
||||
public DataSource runeliteDataSource(@Qualifier("dataSourceRuneLite") DataSourceProperties dataSourceProperties)
|
||||
{
|
||||
return getDataSource(dataSourceProperties);
|
||||
}
|
||||
|
||||
@Bean(value = "runelite-cache", destroyMethod = "")
|
||||
public DataSource runeliteCache2DataSource(@Qualifier("dataSourceRuneLiteCache") DataSourceProperties dataSourceProperties)
|
||||
{
|
||||
return getDataSource(dataSourceProperties);
|
||||
}
|
||||
|
||||
@Bean("Runelite SQL2O")
|
||||
public Sql2o sql2o(@Qualifier("runelite") DataSource dataSource)
|
||||
{
|
||||
return createSql2oFromDataSource(dataSource);
|
||||
}
|
||||
|
||||
@Bean("Runelite Cache SQL2O")
|
||||
public Sql2o cacheSql2o(@Qualifier("runelite-cache") DataSource dataSource)
|
||||
{
|
||||
return createSql2oFromDataSource(dataSource);
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "")
|
||||
public MongoClient mongoClient(@Value("${mongo.host:}") String host, @Value("${mongo.jndiName:}") String jndiName) throws NamingException
|
||||
{
|
||||
if (!Strings.isNullOrEmpty(jndiName))
|
||||
{
|
||||
JndiTemplate jndiTemplate = new JndiTemplate();
|
||||
return jndiTemplate.lookup(jndiName, MongoClient.class);
|
||||
}
|
||||
else if (!Strings.isNullOrEmpty(host))
|
||||
{
|
||||
return MongoClients.create(host);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Either mongo.host or mongo.jndiName must be set");
|
||||
}
|
||||
}
|
||||
|
||||
private static DataSource getDataSource(DataSourceProperties dataSourceProperties)
|
||||
{
|
||||
if (!Strings.isNullOrEmpty(dataSourceProperties.getJndiName()))
|
||||
{
|
||||
// Use JNDI provided datasource, which is already configured with pooling
|
||||
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
|
||||
return dataSourceLookup.getDataSource(dataSourceProperties.getJndiName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return dataSourceProperties.initializeDataSourceBuilder().build();
|
||||
}
|
||||
}
|
||||
|
||||
private static Sql2o createSql2oFromDataSource(final DataSource dataSource)
|
||||
{
|
||||
final Map<Class, Converter> converters = new HashMap<>();
|
||||
converters.put(Instant.class, new InstantConverter());
|
||||
return new Sql2o(dataSource, new NoQuirks(converters));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
|
||||
{
|
||||
return application.sources(SpringBootWebApplication.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException
|
||||
{
|
||||
super.onStartup(servletContext);
|
||||
ILoggerFactory loggerFactory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
||||
if (loggerFactory instanceof LoggerContext)
|
||||
{
|
||||
LoggerContext loggerContext = (LoggerContext) loggerFactory;
|
||||
loggerContext.setPackagingDataEnabled(false);
|
||||
log.debug("Disabling logback packaging data");
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OkHttpClient okHttpClient(
|
||||
@Value("${runelite.version}") String version,
|
||||
@Value("${runelite.commit}") String commit,
|
||||
@Value("${runelite.dirty}") boolean dirty
|
||||
)
|
||||
{
|
||||
final String userAgent = "RuneLite/" + version + "-" + commit + (dirty ? "+" : "");
|
||||
return new OkHttpClient.Builder()
|
||||
.pingInterval(30, TimeUnit.SECONDS)
|
||||
.addNetworkInterceptor(chain ->
|
||||
{
|
||||
Request userAgentRequest = chain.request()
|
||||
.newBuilder()
|
||||
.header("User-Agent", userAgent)
|
||||
.build();
|
||||
return chain.proceed(userAgentRequest);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(SpringBootWebApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
||||
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
|
||||
@Configuration
|
||||
public class SpringSchedulingConfigurer implements SchedulingConfigurer
|
||||
{
|
||||
@Override
|
||||
public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
|
||||
{
|
||||
// this is from ScheduledTaskRegistrar.scheduleTasks() but modified to give the scheduler thread a
|
||||
// recognizable name
|
||||
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
|
||||
new ThreadFactoryBuilder()
|
||||
.setNameFormat("scheduler-%d")
|
||||
.build()
|
||||
);
|
||||
TaskScheduler scheduler = new ConcurrentTaskScheduler(scheduledExecutorService);
|
||||
taskRegistrar.setTaskScheduler(scheduler);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service;
|
||||
|
||||
import java.util.List;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class SpringWebMvcConfigurer extends WebMvcConfigurerAdapter
|
||||
{
|
||||
/**
|
||||
* Configure .js as application/json to trick Cloudflare into caching json responses
|
||||
*/
|
||||
@Override
|
||||
public void configureContentNegotiation(ContentNegotiationConfigurer configurer)
|
||||
{
|
||||
configurer.mediaType("js", MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use GSON instead of Jackson for JSON serialization
|
||||
* @param converters
|
||||
*/
|
||||
@Override
|
||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters)
|
||||
{
|
||||
// Could not figure out a better way to force GSON
|
||||
converters.removeIf(MappingJackson2HttpMessageConverter.class::isInstance);
|
||||
|
||||
GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
|
||||
gsonHttpMessageConverter.setGson(RuneLiteAPI.GSON);
|
||||
converters.add(gsonHttpMessageConverter);
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account;
|
||||
|
||||
import com.github.scribejava.apis.GoogleApi20;
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.model.OAuthRequest;
|
||||
import com.github.scribejava.core.model.Response;
|
||||
import com.github.scribejava.core.model.Verb;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.account.OAuthResponse;
|
||||
import net.runelite.http.api.ws.WebsocketGsonFactory;
|
||||
import net.runelite.http.api.ws.WebsocketMessage;
|
||||
import net.runelite.http.api.ws.messages.LoginResponse;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import net.runelite.http.service.account.beans.UserEntry;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Sql2o;
|
||||
import org.sql2o.Sql2oException;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/account")
|
||||
public class AccountService
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(AccountService.class);
|
||||
|
||||
private static final String CREATE_SESSIONS = "CREATE TABLE IF NOT EXISTS `sessions` (\n"
|
||||
+ " `user` int(11) NOT NULL PRIMARY KEY,\n"
|
||||
+ " `uuid` varchar(36) NOT NULL,\n"
|
||||
+ " `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
|
||||
+ " `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
|
||||
+ " UNIQUE KEY `uuid` (`uuid`),\n"
|
||||
+ " KEY `user` (`user`)\n"
|
||||
+ ") ENGINE=InnoDB";
|
||||
|
||||
private static final String CREATE_USERS = "CREATE TABLE IF NOT EXISTS `users` (\n"
|
||||
+ " `id` int(11) NOT NULL AUTO_INCREMENT,\n"
|
||||
+ " `username` tinytext NOT NULL,\n"
|
||||
+ " `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
|
||||
+ " PRIMARY KEY (`id`),\n"
|
||||
+ " UNIQUE KEY `username` (`username`(64))\n"
|
||||
+ ") ENGINE=InnoDB";
|
||||
|
||||
private static final String SESSIONS_FK = "ALTER TABLE `sessions`\n"
|
||||
+ " ADD CONSTRAINT `id` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;";
|
||||
|
||||
private static final String SCOPE = "https://www.googleapis.com/auth/userinfo.email";
|
||||
private static final String USERINFO = "https://www.googleapis.com/oauth2/v2/userinfo";
|
||||
private static final String RL_REDIR = "https://runelite.net/logged-in";
|
||||
|
||||
private final Gson gson = RuneLiteAPI.GSON;
|
||||
private final Gson websocketGson = WebsocketGsonFactory.build();
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final String oauthClientId;
|
||||
private final String oauthClientSecret;
|
||||
private final String oauthCallback;
|
||||
private final String runeliteVersion;
|
||||
private final AuthFilter auth;
|
||||
private final RedisPool jedisPool;
|
||||
|
||||
@Autowired
|
||||
public AccountService(
|
||||
@Qualifier("Runelite SQL2O") Sql2o sql2o,
|
||||
@Value("${oauth.client-id}") String oauthClientId,
|
||||
@Value("${oauth.client-secret}") String oauthClientSecret,
|
||||
@Value("${oauth.callback}") String oauthCallback,
|
||||
@Value("${runelite.version}") String runeliteVersion,
|
||||
AuthFilter auth,
|
||||
RedisPool jedisPool
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.oauthClientId = oauthClientId;
|
||||
this.oauthClientSecret = oauthClientSecret;
|
||||
this.oauthCallback = oauthCallback;
|
||||
this.runeliteVersion = runeliteVersion;
|
||||
this.auth = auth;
|
||||
this.jedisPool = jedisPool;
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE_SESSIONS)
|
||||
.executeUpdate();
|
||||
|
||||
con.createQuery(CREATE_USERS)
|
||||
.executeUpdate();
|
||||
|
||||
try
|
||||
{
|
||||
con.createQuery(SESSIONS_FK)
|
||||
.executeUpdate();
|
||||
}
|
||||
catch (Sql2oException ex)
|
||||
{
|
||||
// Ignore, happens when index already exists
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public OAuthResponse login(@RequestParam UUID uuid)
|
||||
{
|
||||
State state = new State();
|
||||
state.setUuid(uuid);
|
||||
state.setApiVersion(runeliteVersion);
|
||||
|
||||
OAuth20Service service = new ServiceBuilder()
|
||||
.apiKey(oauthClientId)
|
||||
.apiSecret(oauthClientSecret)
|
||||
.scope(SCOPE)
|
||||
.callback(oauthCallback)
|
||||
.state(gson.toJson(state))
|
||||
.build(GoogleApi20.instance());
|
||||
|
||||
final Map<String, String> additionalParams = new HashMap<>();
|
||||
additionalParams.put("prompt", "select_account");
|
||||
|
||||
String authorizationUrl = service.getAuthorizationUrl(additionalParams);
|
||||
|
||||
OAuthResponse lr = new OAuthResponse();
|
||||
lr.setOauthUrl(authorizationUrl);
|
||||
lr.setUid(uuid);
|
||||
|
||||
return lr;
|
||||
}
|
||||
|
||||
@GetMapping("/callback")
|
||||
public Object callback(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestParam(required = false) String error,
|
||||
@RequestParam String code,
|
||||
@RequestParam("state") String stateStr
|
||||
) throws InterruptedException, ExecutionException, IOException
|
||||
{
|
||||
if (error != null)
|
||||
{
|
||||
logger.info("Error in oauth callback: {}", error);
|
||||
return null;
|
||||
}
|
||||
|
||||
State state = gson.fromJson(stateStr, State.class);
|
||||
|
||||
logger.info("Got authorization code {} for uuid {}", code, state.getUuid());
|
||||
|
||||
OAuth20Service service = new ServiceBuilder()
|
||||
.apiKey(oauthClientId)
|
||||
.apiSecret(oauthClientSecret)
|
||||
.scope(SCOPE)
|
||||
.callback(oauthCallback)
|
||||
.state(gson.toJson(state))
|
||||
.build(GoogleApi20.instance());
|
||||
|
||||
OAuth2AccessToken accessToken = service.getAccessToken(code);
|
||||
|
||||
// Access user info
|
||||
OAuthRequest orequest = new OAuthRequest(Verb.GET, USERINFO);
|
||||
service.signRequest(accessToken, orequest);
|
||||
|
||||
Response oresponse = service.execute(orequest);
|
||||
|
||||
if (oresponse.getCode() / 100 != 2)
|
||||
{
|
||||
// Could be a forged result
|
||||
return null;
|
||||
}
|
||||
|
||||
UserInfo userInfo = gson.fromJson(oresponse.getBody(), UserInfo.class);
|
||||
|
||||
logger.info("Got user info: {}", userInfo);
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("insert ignore into users (username) values (:username)")
|
||||
.addParameter("username", userInfo.getEmail())
|
||||
.executeUpdate();
|
||||
|
||||
UserEntry user = con.createQuery("select id from users where username = :username")
|
||||
.addParameter("username", userInfo.getEmail())
|
||||
.executeAndFetchFirst(UserEntry.class);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
logger.warn("Unable to find newly created user session");
|
||||
return null; // that's weird
|
||||
}
|
||||
|
||||
// insert session
|
||||
con.createQuery("insert ignore into sessions (user, uuid) values (:user, :uuid)")
|
||||
.addParameter("user", user.getId())
|
||||
.addParameter("uuid", state.getUuid().toString())
|
||||
.executeUpdate();
|
||||
|
||||
logger.info("Created session for user {}", userInfo.getEmail());
|
||||
}
|
||||
|
||||
response.sendRedirect(RL_REDIR);
|
||||
|
||||
notifySession(state.getUuid(), userInfo.getEmail());
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private void notifySession(UUID uuid, String username)
|
||||
{
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setUsername(username);
|
||||
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.publish("session." + uuid, websocketGson.toJson(response, WebsocketMessage.class));
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/logout")
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
SessionEntry session = auth.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auth.invalidate(session.getUuid());
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from sessions where uuid = :uuid")
|
||||
.addParameter("uuid", session.getUuid().toString())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/session-check")
|
||||
public void sessionCheck(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
auth.handle(request, response);
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
public class AuthFilter
|
||||
{
|
||||
private final Sql2o sql2o;
|
||||
|
||||
private final Cache<UUID, SessionEntry> sessionCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(10000L)
|
||||
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||
.removalListener(this::removalListener)
|
||||
.build();
|
||||
|
||||
@Autowired
|
||||
public AuthFilter(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
}
|
||||
|
||||
public SessionEntry handle(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
String runeliteAuth = request.getHeader(RuneLiteAPI.RUNELITE_AUTH);
|
||||
if (runeliteAuth == null)
|
||||
{
|
||||
response.sendError(401, "Access denied");
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID uuid = UUID.fromString(runeliteAuth);
|
||||
SessionEntry sessionEntry = sessionCache.getIfPresent(uuid);
|
||||
if (sessionEntry != null)
|
||||
{
|
||||
return sessionEntry;
|
||||
}
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
sessionEntry = con.createQuery("select user, uuid, created, last_used as lastUsed from sessions where uuid = :uuid")
|
||||
.addParameter("uuid", uuid.toString())
|
||||
.executeAndFetchFirst(SessionEntry.class);
|
||||
}
|
||||
|
||||
if (sessionEntry == null)
|
||||
{
|
||||
response.sendError(401, "Access denied");
|
||||
return null;
|
||||
}
|
||||
|
||||
sessionCache.put(uuid, sessionEntry);
|
||||
|
||||
return sessionEntry;
|
||||
}
|
||||
|
||||
private void removalListener(RemovalNotification<UUID, SessionEntry> notification)
|
||||
{
|
||||
UUID uuid = notification.getKey();
|
||||
Instant now = Instant.now();
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("update sessions set last_used = :last_used where uuid = :uuid")
|
||||
.addParameter("last_used", Timestamp.from(now))
|
||||
.addParameter("uuid", uuid.toString())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidate(UUID uuid)
|
||||
{
|
||||
// If we ever run multiple services, may need to publish something here to invalidate...
|
||||
sessionCache.invalidate(uuid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class State
|
||||
{
|
||||
private UUID uuid;
|
||||
private String apiVersion;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account;
|
||||
|
||||
public class UserInfo
|
||||
{
|
||||
private String email;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "UserInfo{" + "email=" + email + '}';
|
||||
}
|
||||
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account.beans;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SessionEntry
|
||||
{
|
||||
private int user;
|
||||
private UUID uuid;
|
||||
private Instant created;
|
||||
private Instant lastUsed;
|
||||
|
||||
public int getUser()
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(int user)
|
||||
{
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public UUID getUuid()
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(UUID uuid)
|
||||
{
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public Instant getCreated()
|
||||
{
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Instant created)
|
||||
{
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Instant getLastUsed()
|
||||
{
|
||||
return lastUsed;
|
||||
}
|
||||
|
||||
public void setLastUsed(Instant lastUsed)
|
||||
{
|
||||
this.lastUsed = lastUsed;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.account.beans;
|
||||
|
||||
public class UserEntry
|
||||
{
|
||||
private int id;
|
||||
private String username;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "UserEntry{" + "id=" + id + ", username=" + username + '}';
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache;
|
||||
|
||||
import java.util.List;
|
||||
import net.runelite.cache.IndexType;
|
||||
import net.runelite.http.service.cache.beans.ArchiveEntry;
|
||||
import net.runelite.http.service.cache.beans.CacheEntry;
|
||||
import net.runelite.http.service.cache.beans.FileEntry;
|
||||
import net.runelite.http.service.cache.beans.IndexEntry;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.ResultSetIterable;
|
||||
|
||||
class CacheDAO
|
||||
{
|
||||
public List<CacheEntry> listCaches(Connection con)
|
||||
{
|
||||
return con.createQuery("select id, revision, date from cache")
|
||||
.executeAndFetch(CacheEntry.class);
|
||||
}
|
||||
|
||||
public CacheEntry findMostRecent(Connection con)
|
||||
{
|
||||
return con.createQuery("select id, revision, date from cache order by revision desc, date desc limit 1")
|
||||
.executeAndFetchFirst(CacheEntry.class);
|
||||
}
|
||||
|
||||
public List<IndexEntry> findIndexesForCache(Connection con, CacheEntry cache)
|
||||
{
|
||||
return con.createQuery("select id, indexId, crc, revision from `index` where cache = :cache")
|
||||
.addParameter("cache", cache.getId())
|
||||
.executeAndFetch(IndexEntry.class);
|
||||
}
|
||||
|
||||
public IndexEntry findIndexForCache(Connection con, CacheEntry cache, int indexId)
|
||||
{
|
||||
return con.createQuery("select id, indexId, crc, revision from `index` "
|
||||
+ "where cache = :id "
|
||||
+ "and indexId = :indexId")
|
||||
.addParameter("id", cache.getId())
|
||||
.addParameter("indexId", indexId)
|
||||
.executeAndFetchFirst(IndexEntry.class);
|
||||
}
|
||||
|
||||
public ResultSetIterable<ArchiveEntry> findArchivesForIndex(Connection con, IndexEntry indexEntry)
|
||||
{
|
||||
return con.createQuery("select archive.id, archive.archiveId, archive.nameHash,"
|
||||
+ " archive.crc, archive.revision, archive.hash from index_archive "
|
||||
+ "join archive on index_archive.archive = archive.id "
|
||||
+ "where index_archive.index = :id")
|
||||
.addParameter("id", indexEntry.getId())
|
||||
.executeAndFetchLazy(ArchiveEntry.class);
|
||||
}
|
||||
|
||||
public ArchiveEntry findArchiveForIndex(Connection con, IndexEntry indexEntry, int archiveId)
|
||||
{
|
||||
return con.createQuery("select archive.id, archive.archiveId, archive.nameHash,"
|
||||
+ " archive.crc, archive.revision, archive.hash from index_archive "
|
||||
+ "join archive on index_archive.archive = archive.id "
|
||||
+ "where index_archive.index = :id "
|
||||
+ "and archive.archiveId = :archiveId")
|
||||
.addParameter("id", indexEntry.getId())
|
||||
.addParameter("archiveId", archiveId)
|
||||
.executeAndFetchFirst(ArchiveEntry.class);
|
||||
}
|
||||
|
||||
public ArchiveEntry findArchiveByName(Connection con, CacheEntry cache, IndexType index, int nameHash)
|
||||
{
|
||||
return con.createQuery("select archive.id, archive.archiveId, archive.nameHash,"
|
||||
+ " archive.crc, archive.revision, archive.hash from archive "
|
||||
+ "join index_archive on index_archive.archive = archive.id "
|
||||
+ "join `index` on index.id = index_archive.index "
|
||||
+ "where index.cache = :cacheId "
|
||||
+ "and index.indexId = :indexId "
|
||||
+ "and archive.nameHash = :nameHash "
|
||||
+ "limit 1")
|
||||
.addParameter("cacheId", cache.getId())
|
||||
.addParameter("indexId", index.getNumber())
|
||||
.addParameter("nameHash", nameHash)
|
||||
.executeAndFetchFirst(ArchiveEntry.class);
|
||||
}
|
||||
|
||||
public ResultSetIterable<FileEntry> findFilesForArchive(Connection con, ArchiveEntry archiveEntry)
|
||||
{
|
||||
Query findFilesForArchive = con.createQuery("select id, fileId, nameHash from file "
|
||||
+ "where archive = :archive");
|
||||
|
||||
return findFilesForArchive
|
||||
.addParameter("archive", archiveEntry.getId())
|
||||
.executeAndFetchLazy(FileEntry.class);
|
||||
}
|
||||
|
||||
public CacheEntry findCache(Connection con, int cacheId)
|
||||
{
|
||||
return con.createQuery("select id, revision, date from cache "
|
||||
+ "where id = :cacheId")
|
||||
.addParameter("cacheId", cacheId)
|
||||
.executeAndFetchFirst(CacheEntry.class);
|
||||
}
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.errors.ErrorResponseException;
|
||||
import io.minio.errors.InsufficientDataException;
|
||||
import io.minio.errors.InternalException;
|
||||
import io.minio.errors.InvalidArgumentException;
|
||||
import io.minio.errors.InvalidBucketNameException;
|
||||
import io.minio.errors.InvalidEndpointException;
|
||||
import io.minio.errors.InvalidPortException;
|
||||
import io.minio.errors.NoResponseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.cache.ConfigType;
|
||||
import net.runelite.cache.IndexType;
|
||||
import net.runelite.cache.definitions.ItemDefinition;
|
||||
import net.runelite.cache.definitions.loaders.ItemLoader;
|
||||
import net.runelite.cache.fs.ArchiveFiles;
|
||||
import net.runelite.cache.fs.Container;
|
||||
import net.runelite.cache.fs.FSFile;
|
||||
import net.runelite.http.service.cache.beans.ArchiveEntry;
|
||||
import net.runelite.http.service.cache.beans.CacheEntry;
|
||||
import net.runelite.http.service.cache.beans.FileEntry;
|
||||
import net.runelite.http.service.cache.beans.IndexEntry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.ResultSetIterable;
|
||||
import org.sql2o.Sql2o;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class CacheService
|
||||
{
|
||||
@Autowired
|
||||
@Qualifier("Runelite Cache SQL2O")
|
||||
private Sql2o sql2o;
|
||||
|
||||
@Value("${minio.bucket}")
|
||||
private String minioBucket;
|
||||
|
||||
private final MinioClient minioClient;
|
||||
|
||||
@Autowired
|
||||
public CacheService(
|
||||
@Value("${minio.endpoint}") String minioEndpoint,
|
||||
@Value("${minio.accesskey}") String accessKey,
|
||||
@Value("${minio.secretkey}") String secretKey
|
||||
) throws InvalidEndpointException, InvalidPortException
|
||||
{
|
||||
this.minioClient = new MinioClient(minioEndpoint, accessKey, secretKey);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MinioClient minioClient()
|
||||
{
|
||||
return minioClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve archive from storage
|
||||
*
|
||||
* @param archiveEntry
|
||||
* @return
|
||||
*/
|
||||
public byte[] getArchive(ArchiveEntry archiveEntry)
|
||||
{
|
||||
String hashStr = BaseEncoding.base16().encode(archiveEntry.getHash());
|
||||
String path = new StringBuilder()
|
||||
.append(hashStr, 0, 2)
|
||||
.append('/')
|
||||
.append(hashStr.substring(2))
|
||||
.toString();
|
||||
|
||||
try (InputStream in = minioClient.getObject(minioBucket, path))
|
||||
{
|
||||
return ByteStreams.toByteArray(in);
|
||||
}
|
||||
catch (InvalidBucketNameException | NoSuchAlgorithmException | InsufficientDataException
|
||||
| IOException | InvalidKeyException | NoResponseException | XmlPullParserException
|
||||
| ErrorResponseException | InternalException | InvalidArgumentException ex)
|
||||
{
|
||||
log.warn(null, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ArchiveFiles getArchiveFiles(ArchiveEntry archiveEntry) throws IOException
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
|
||||
try (Connection con = sql2o.open();
|
||||
ResultSetIterable<FileEntry> files = cacheDao.findFilesForArchive(con, archiveEntry))
|
||||
{
|
||||
byte[] archiveData = getArchive(archiveEntry);
|
||||
|
||||
if (archiveData == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Container result = Container.decompress(archiveData, null);
|
||||
if (result == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] decompressedData = result.data;
|
||||
|
||||
ArchiveFiles archiveFiles = new ArchiveFiles();
|
||||
for (FileEntry fileEntry : files)
|
||||
{
|
||||
FSFile file = new FSFile(fileEntry.getFileId());
|
||||
archiveFiles.addFile(file);
|
||||
file.setNameHash(fileEntry.getNameHash());
|
||||
}
|
||||
archiveFiles.loadContents(decompressedData);
|
||||
return archiveFiles;
|
||||
}
|
||||
}
|
||||
|
||||
public List<CacheEntry> listCaches()
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.listCaches(con);
|
||||
}
|
||||
}
|
||||
|
||||
public CacheEntry findCache(int cacheId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findCache(con, cacheId);
|
||||
}
|
||||
}
|
||||
|
||||
public CacheEntry findMostRecent()
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findMostRecent(con);
|
||||
}
|
||||
}
|
||||
|
||||
public List<IndexEntry> findIndexesForCache(CacheEntry cacheEntry)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findIndexesForCache(con, cacheEntry);
|
||||
}
|
||||
}
|
||||
|
||||
public IndexEntry findIndexForCache(CacheEntry cahceEntry, int indexId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findIndexForCache(con, cahceEntry, indexId);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ArchiveEntry> findArchivesForIndex(IndexEntry indexEntry)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
ResultSetIterable<ArchiveEntry> archiveEntries = cacheDao.findArchivesForIndex(con, indexEntry);
|
||||
List<ArchiveEntry> archives = new ArrayList<>();
|
||||
Iterables.addAll(archives, archiveEntries);
|
||||
return archives;
|
||||
}
|
||||
}
|
||||
|
||||
public ArchiveEntry findArchiveForIndex(IndexEntry indexEntry, int archiveId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findArchiveForIndex(con, indexEntry, archiveId);
|
||||
}
|
||||
}
|
||||
|
||||
public ArchiveEntry findArchiveForTypeAndName(CacheEntry cache, IndexType index, int nameHash)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
return cacheDao.findArchiveByName(con, cache, index, nameHash);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ItemDefinition> getItems() throws IOException
|
||||
{
|
||||
CacheEntry cache = findMostRecent();
|
||||
if (cache == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
IndexEntry indexEntry = findIndexForCache(cache, IndexType.CONFIGS.getNumber());
|
||||
ArchiveEntry archiveEntry = findArchiveForIndex(indexEntry, ConfigType.ITEM.getId());
|
||||
ArchiveFiles archiveFiles = getArchiveFiles(archiveEntry);
|
||||
final ItemLoader itemLoader = new ItemLoader();
|
||||
final List<ItemDefinition> result = new ArrayList<>(archiveFiles.getFiles().size());
|
||||
for (FSFile file : archiveFiles.getFiles())
|
||||
{
|
||||
ItemDefinition itemDef = itemLoader.load(file.getFileId(), file.getContents());
|
||||
result.add(itemDef);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ArchiveEntry
|
||||
{
|
||||
private int id;
|
||||
private int archiveId;
|
||||
private int nameHash;
|
||||
private int crc;
|
||||
private int revision;
|
||||
private byte[] hash;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache.beans;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CacheEntry
|
||||
{
|
||||
private int id;
|
||||
private int revision;
|
||||
private Instant date;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileEntry
|
||||
{
|
||||
private int id;
|
||||
private int archiveId;
|
||||
private int fileId;
|
||||
private int nameHash;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.cache.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class IndexEntry
|
||||
{
|
||||
private int id;
|
||||
private int indexId;
|
||||
private int crc;
|
||||
private int revision;
|
||||
}
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.chat;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import net.runelite.http.api.chat.Duels;
|
||||
import net.runelite.http.api.chat.LayoutRoom;
|
||||
import net.runelite.http.api.chat.Task;
|
||||
import net.runelite.http.service.util.exception.NotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/chat")
|
||||
public class ChatController
|
||||
{
|
||||
private static final Pattern STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]");
|
||||
private static final int STRING_MAX_LENGTH = 50;
|
||||
private static final int MAX_LAYOUT_ROOMS = 16;
|
||||
private static final int MAX_PETS = 256;
|
||||
|
||||
private final Cache<KillCountKey, Integer> killCountCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||
.maximumSize(128L)
|
||||
.build();
|
||||
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
|
||||
@PostMapping("/kc")
|
||||
public void submitKc(@RequestParam String name, @RequestParam String boss, @RequestParam int kc)
|
||||
{
|
||||
if (kc <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setKc(name, boss, kc);
|
||||
killCountCache.put(new KillCountKey(name, boss), kc);
|
||||
}
|
||||
|
||||
@GetMapping("/kc")
|
||||
public int getKc(@RequestParam String name, @RequestParam String boss)
|
||||
{
|
||||
Integer kc = killCountCache.getIfPresent(new KillCountKey(name, boss));
|
||||
if (kc == null)
|
||||
{
|
||||
kc = chatService.getKc(name, boss);
|
||||
if (kc != null)
|
||||
{
|
||||
killCountCache.put(new KillCountKey(name, boss), kc);
|
||||
}
|
||||
}
|
||||
|
||||
if (kc == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return kc;
|
||||
}
|
||||
|
||||
@PostMapping("/qp")
|
||||
public void submitQp(@RequestParam String name, @RequestParam int qp)
|
||||
{
|
||||
if (qp < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setQp(name, qp);
|
||||
}
|
||||
|
||||
@GetMapping("/qp")
|
||||
public int getQp(@RequestParam String name)
|
||||
{
|
||||
Integer kc = chatService.getQp(name);
|
||||
if (kc == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return kc;
|
||||
}
|
||||
|
||||
@PostMapping("/gc")
|
||||
public void submitGc(@RequestParam String name, @RequestParam int gc)
|
||||
{
|
||||
if (gc < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setGc(name, gc);
|
||||
}
|
||||
|
||||
@GetMapping("/gc")
|
||||
public int getKc(@RequestParam String name)
|
||||
{
|
||||
Integer gc = chatService.getGc(name);
|
||||
if (gc == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return gc;
|
||||
}
|
||||
|
||||
@PostMapping("/task")
|
||||
public void submitTask(@RequestParam String name, @RequestParam("task") String taskName, @RequestParam int amount,
|
||||
@RequestParam int initialAmount, @RequestParam String location)
|
||||
{
|
||||
Matcher mTask = STRING_VALIDATION.matcher(taskName);
|
||||
Matcher mLocation = STRING_VALIDATION.matcher(location);
|
||||
if (mTask.find() || taskName.length() > STRING_MAX_LENGTH ||
|
||||
mLocation.find() || location.length() > STRING_MAX_LENGTH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task task = new Task();
|
||||
task.setTask(taskName);
|
||||
task.setAmount(amount);
|
||||
task.setInitialAmount(initialAmount);
|
||||
task.setLocation(location);
|
||||
|
||||
chatService.setTask(name, task);
|
||||
}
|
||||
|
||||
@GetMapping("/task")
|
||||
public ResponseEntity<Task> getTask(@RequestParam String name)
|
||||
{
|
||||
Task task = chatService.getTask(name);
|
||||
if (task == null)
|
||||
{
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||
.build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.cacheControl(CacheControl.maxAge(2, TimeUnit.MINUTES).cachePublic())
|
||||
.body(task);
|
||||
}
|
||||
|
||||
@PostMapping("/pb")
|
||||
public void submitPb(@RequestParam String name, @RequestParam String boss, @RequestParam double pb)
|
||||
{
|
||||
if (pb < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setPb(name, boss, pb);
|
||||
}
|
||||
|
||||
@GetMapping("/pb")
|
||||
public double getPb(@RequestParam String name, @RequestParam String boss)
|
||||
{
|
||||
Double pb = chatService.getPb(name, boss);
|
||||
if (pb == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return pb;
|
||||
}
|
||||
|
||||
@PostMapping("/duels")
|
||||
public void submitDuels(@RequestParam String name, @RequestParam int wins,
|
||||
@RequestParam int losses,
|
||||
@RequestParam int winningStreak, @RequestParam int losingStreak)
|
||||
{
|
||||
if (wins < 0 || losses < 0 || winningStreak < 0 || losingStreak < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Duels duels = new Duels();
|
||||
duels.setWins(wins);
|
||||
duels.setLosses(losses);
|
||||
duels.setWinningStreak(winningStreak);
|
||||
duels.setLosingStreak(losingStreak);
|
||||
|
||||
chatService.setDuels(name, duels);
|
||||
}
|
||||
|
||||
@GetMapping("/duels")
|
||||
public Duels getDuels(@RequestParam String name)
|
||||
{
|
||||
Duels duels = chatService.getDuels(name);
|
||||
if (duels == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return duels;
|
||||
}
|
||||
|
||||
@PostMapping("/layout")
|
||||
public void submitLayout(@RequestParam String name, @RequestBody LayoutRoom[] rooms)
|
||||
{
|
||||
if (rooms.length > MAX_LAYOUT_ROOMS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setLayout(name, rooms);
|
||||
}
|
||||
|
||||
@GetMapping("/layout")
|
||||
public LayoutRoom[] getLayout(@RequestParam String name)
|
||||
{
|
||||
LayoutRoom[] layout = chatService.getLayout(name);
|
||||
|
||||
if (layout == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
@PostMapping("/pets")
|
||||
public void submitPetList(@RequestParam String name, @RequestBody int[] petList)
|
||||
{
|
||||
if (petList.length == 0 || petList.length > MAX_PETS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
chatService.setPetList(name, petList);
|
||||
}
|
||||
|
||||
@GetMapping("/pets")
|
||||
public int[] getPetList(@RequestParam String name)
|
||||
{
|
||||
int[] petList = chatService.getPetList(name);
|
||||
if (petList == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return petList;
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.chat;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.runelite.http.api.chat.Duels;
|
||||
import net.runelite.http.api.chat.LayoutRoom;
|
||||
import net.runelite.http.api.chat.Task;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@Service
|
||||
public class ChatService
|
||||
{
|
||||
private static final Duration EXPIRE = Duration.ofMinutes(2);
|
||||
|
||||
private final RedisPool jedisPool;
|
||||
|
||||
@Autowired
|
||||
public ChatService(RedisPool jedisPool)
|
||||
{
|
||||
this.jedisPool = jedisPool;
|
||||
}
|
||||
|
||||
public Integer getKc(String name, String boss)
|
||||
{
|
||||
String value;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
value = jedis.get("kc." + name + "." + boss);
|
||||
}
|
||||
return value == null ? null : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
public void setKc(String name, String boss, int kc)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("kc." + name + "." + boss, (int) EXPIRE.getSeconds(), Integer.toString(kc));
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getQp(String name)
|
||||
{
|
||||
String value;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
value = jedis.get("qp." + name);
|
||||
}
|
||||
return value == null ? null : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
public void setQp(String name, int qp)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("qp." + name, (int) EXPIRE.getSeconds(), Integer.toString(qp));
|
||||
}
|
||||
}
|
||||
|
||||
public Task getTask(String name)
|
||||
{
|
||||
Map<String, String> map;
|
||||
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
map = jedis.hgetAll("task." + name);
|
||||
}
|
||||
|
||||
if (map.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Task task = new Task();
|
||||
task.setTask(map.get("task"));
|
||||
task.setAmount(Integer.parseInt(map.get("amount")));
|
||||
task.setInitialAmount(Integer.parseInt(map.get("initialAmount")));
|
||||
task.setLocation(map.get("location"));
|
||||
return task;
|
||||
}
|
||||
|
||||
public void setTask(String name, Task task)
|
||||
{
|
||||
Map<String, String> taskMap = ImmutableMap.<String, String>builderWithExpectedSize(4)
|
||||
.put("task", task.getTask())
|
||||
.put("amount", Integer.toString(task.getAmount()))
|
||||
.put("initialAmount", Integer.toString(task.getInitialAmount()))
|
||||
.put("location", task.getLocation())
|
||||
.build();
|
||||
|
||||
String key = "task." + name;
|
||||
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.hmset(key, taskMap);
|
||||
jedis.expire(key, (int) EXPIRE.getSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
public Double getPb(String name, String boss)
|
||||
{
|
||||
String value;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
value = jedis.get("pb." + boss + "." + name);
|
||||
}
|
||||
return value == null ? null : Double.parseDouble(value);
|
||||
}
|
||||
|
||||
public void setPb(String name, String boss, double pb)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("pb." + boss + "." + name, (int) EXPIRE.getSeconds(), Double.toString(pb));
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getGc(String name)
|
||||
{
|
||||
String value;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
value = jedis.get("gc." + name);
|
||||
}
|
||||
return value == null ? null : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
public void setGc(String name, int gc)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("gc." + name, (int) EXPIRE.getSeconds(), Integer.toString(gc));
|
||||
}
|
||||
}
|
||||
|
||||
public Duels getDuels(String name)
|
||||
{
|
||||
Map<String, String> map;
|
||||
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
map = jedis.hgetAll("duels." + name);
|
||||
}
|
||||
|
||||
if (map.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Duels duels = new Duels();
|
||||
duels.setWins(Integer.parseInt(map.get("wins")));
|
||||
duels.setLosses(Integer.parseInt(map.get("losses")));
|
||||
duels.setWinningStreak(Integer.parseInt(map.get("winningStreak")));
|
||||
duels.setLosingStreak(Integer.parseInt(map.get("losingStreak")));
|
||||
return duels;
|
||||
}
|
||||
|
||||
public void setDuels(String name, Duels duels)
|
||||
{
|
||||
Map<String, String> duelsMap = ImmutableMap.<String, String>builderWithExpectedSize(4)
|
||||
.put("wins", Integer.toString(duels.getWins()))
|
||||
.put("losses", Integer.toString(duels.getLosses()))
|
||||
.put("winningStreak", Integer.toString(duels.getWinningStreak()))
|
||||
.put("losingStreak", Integer.toString(duels.getLosingStreak()))
|
||||
.build();
|
||||
|
||||
String key = "duels." + name;
|
||||
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.hmset(key, duelsMap);
|
||||
jedis.expire(key, (int) EXPIRE.getSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
public LayoutRoom[] getLayout(String name)
|
||||
{
|
||||
String layout;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
layout = jedis.get("layout." + name);
|
||||
}
|
||||
|
||||
if (layout == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> roomList = Splitter.on(' ').splitToList(layout);
|
||||
return roomList.stream()
|
||||
.map(LayoutRoom::valueOf)
|
||||
.toArray(LayoutRoom[]::new);
|
||||
}
|
||||
|
||||
public void setLayout(String name, LayoutRoom[] rooms)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("layout." + name, (int) EXPIRE.getSeconds(), Joiner.on(' ').join(rooms));
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getPetList(String name)
|
||||
{
|
||||
Set<String> pets;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
pets = jedis.smembers("pets." + name);
|
||||
}
|
||||
|
||||
if (pets.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return pets.stream()
|
||||
.mapToInt(Integer::parseInt)
|
||||
.toArray();
|
||||
}
|
||||
|
||||
public void setPetList(String name, int[] petList)
|
||||
{
|
||||
String[] pets = Arrays.stream(petList).mapToObj(Integer::toString).toArray(String[]::new);
|
||||
String key = "pets." + name;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.sadd(key, pets);
|
||||
jedis.expire(key, (int) EXPIRE.getSeconds());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.chat;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
class KillCountKey
|
||||
{
|
||||
private String username;
|
||||
private String boss;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.config.Configuration;
|
||||
import net.runelite.http.service.account.AuthFilter;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/config")
|
||||
public class ConfigController
|
||||
{
|
||||
private final ConfigService configService;
|
||||
private final AuthFilter authFilter;
|
||||
|
||||
@Autowired
|
||||
public ConfigController(ConfigService configService, AuthFilter authFilter)
|
||||
{
|
||||
this.configService = configService;
|
||||
this.authFilter = authFilter;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Configuration get(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return configService.get(session.getUser());
|
||||
}
|
||||
|
||||
@PatchMapping
|
||||
public List<String> patch(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestBody Configuration changes
|
||||
) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
if (session == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> failures = configService.patch(session.getUser(), changes);
|
||||
if (failures.size() != 0)
|
||||
{
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return failures;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{key:.+}", method = PUT)
|
||||
public void setKey(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@PathVariable String key,
|
||||
@RequestBody(required = false) String value
|
||||
) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!configService.setKey(session.getUser(), key, value))
|
||||
{
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{key:.+}", method = DELETE)
|
||||
public void unsetKey(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@PathVariable String key
|
||||
) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!configService.unsetKey(session.getUser(), key))
|
||||
{
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.config;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import static com.mongodb.client.model.Filters.eq;
|
||||
import com.mongodb.client.model.IndexOptions;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import static com.mongodb.client.model.Updates.combine;
|
||||
import static com.mongodb.client.model.Updates.set;
|
||||
import static com.mongodb.client.model.Updates.unset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.config.ConfigEntry;
|
||||
import net.runelite.http.api.config.Configuration;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ConfigService
|
||||
{
|
||||
private static final Pattern MAYBE_JSON = Pattern.compile("^[\\-0-9{\\[\"]|true|false");
|
||||
private static final int MAX_DEPTH = 8;
|
||||
private static final int MAX_VALUE_LENGTH = 262144;
|
||||
|
||||
private final Gson GSON = RuneLiteAPI.GSON;
|
||||
private final UpdateOptions upsertUpdateOptions = new UpdateOptions().upsert(true);
|
||||
|
||||
private final MongoCollection<Document> mongoCollection;
|
||||
|
||||
@Autowired
|
||||
public ConfigService(
|
||||
MongoClient mongoClient,
|
||||
@Value("${mongo.database}") String databaseName
|
||||
)
|
||||
{
|
||||
|
||||
MongoDatabase database = mongoClient.getDatabase(databaseName);
|
||||
MongoCollection<Document> collection = database.getCollection("config");
|
||||
this.mongoCollection = collection;
|
||||
|
||||
// Create unique index on _userId
|
||||
IndexOptions indexOptions = new IndexOptions().unique(true);
|
||||
collection.createIndex(Indexes.ascending("_userId"), indexOptions);
|
||||
}
|
||||
|
||||
private Document getConfig(int userId)
|
||||
{
|
||||
return mongoCollection.find(eq("_userId", userId)).first();
|
||||
}
|
||||
|
||||
public Configuration get(int userId)
|
||||
{
|
||||
Map<String, Object> configMap = getConfig(userId);
|
||||
|
||||
if (configMap == null || configMap.isEmpty())
|
||||
{
|
||||
return new Configuration(Collections.emptyList());
|
||||
}
|
||||
|
||||
List<ConfigEntry> config = new ArrayList<>();
|
||||
|
||||
for (String group : configMap.keySet())
|
||||
{
|
||||
// Reserved keys
|
||||
if (group.startsWith("_") || group.startsWith("$"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, Object> groupMap = (Map) configMap.get(group);
|
||||
|
||||
for (Map.Entry<String, Object> entry : groupMap.entrySet())
|
||||
{
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (value instanceof Map || value instanceof Collection)
|
||||
{
|
||||
value = GSON.toJson(entry.getValue());
|
||||
}
|
||||
else if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigEntry configEntry = new ConfigEntry();
|
||||
configEntry.setKey(group + "." + key.replace(':', '.'));
|
||||
configEntry.setValue(value.toString());
|
||||
config.add(configEntry);
|
||||
}
|
||||
}
|
||||
|
||||
return new Configuration(config);
|
||||
}
|
||||
|
||||
public List<String> patch(int userID, Configuration config)
|
||||
{
|
||||
List<String> failures = new ArrayList<>();
|
||||
List<Bson> sets = new ArrayList<>(config.getConfig().size());
|
||||
for (ConfigEntry entry : config.getConfig())
|
||||
{
|
||||
Bson s = setForKV(entry.getKey(), entry.getValue());
|
||||
if (s == null)
|
||||
{
|
||||
failures.add(entry.getKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
sets.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (sets.size() > 0)
|
||||
{
|
||||
mongoCollection.updateOne(
|
||||
eq("_userId", userID),
|
||||
combine(sets),
|
||||
upsertUpdateOptions
|
||||
);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Bson setForKV(String key, @Nullable String value)
|
||||
{
|
||||
if (key.startsWith("$") || key.startsWith("_"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] split = key.split("\\.", 2);
|
||||
if (split.length != 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String dbKey = split[0] + "." + split[1].replace('.', ':');
|
||||
|
||||
if (Strings.isNullOrEmpty(value))
|
||||
{
|
||||
return unset(dbKey);
|
||||
}
|
||||
|
||||
Object jsonValue;
|
||||
if (!isMaybeJson(value))
|
||||
{
|
||||
if (!validateStr(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
jsonValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!validateJson(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
jsonValue = parseJsonString(value);
|
||||
}
|
||||
return set(dbKey, jsonValue);
|
||||
}
|
||||
|
||||
public boolean setKey(
|
||||
int userId,
|
||||
String key,
|
||||
@Nullable String value
|
||||
)
|
||||
{
|
||||
Bson set = setForKV(key, value);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mongoCollection.updateOne(eq("_userId", userId),
|
||||
set,
|
||||
upsertUpdateOptions);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean unsetKey(
|
||||
int userId,
|
||||
String key
|
||||
)
|
||||
{
|
||||
Bson set = setForKV(key, null);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mongoCollection.updateOne(eq("_userId", userId), set);
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Object parseJsonString(String value)
|
||||
{
|
||||
Object jsonValue;
|
||||
try
|
||||
{
|
||||
jsonValue = RuneLiteAPI.GSON.fromJson(value, Object.class);
|
||||
if (jsonValue == null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else if (jsonValue instanceof Double || jsonValue instanceof Float)
|
||||
{
|
||||
Number number = (Number) jsonValue;
|
||||
if (Math.floor(number.doubleValue()) == number.doubleValue() && !Double.isInfinite(number.doubleValue()))
|
||||
{
|
||||
// value is an int or long. 'number' might be truncated so parse it from 'value'
|
||||
try
|
||||
{
|
||||
jsonValue = Integer.parseInt(value);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
jsonValue = Long.parseLong(value);
|
||||
}
|
||||
catch (NumberFormatException ex2)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonSyntaxException ex)
|
||||
{
|
||||
jsonValue = value;
|
||||
}
|
||||
return jsonValue;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isMaybeJson(String value)
|
||||
{
|
||||
return MAYBE_JSON.matcher(value).find();
|
||||
}
|
||||
|
||||
private static boolean validateStr(String value)
|
||||
{
|
||||
return value.length() < MAX_VALUE_LENGTH;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean validateJson(String value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// I couldn't figure out a better way to do this than a second json parse
|
||||
JsonElement jsonElement = RuneLiteAPI.GSON.fromJson(value, JsonElement.class);
|
||||
if (jsonElement == null)
|
||||
{
|
||||
return value.length() < MAX_VALUE_LENGTH;
|
||||
}
|
||||
return validateObject(jsonElement, 1);
|
||||
}
|
||||
catch (JsonSyntaxException ex)
|
||||
{
|
||||
// the client submits the string representation of objects which is not always valid json,
|
||||
// eg. a value with a ':' in it. We just ignore it now. We can't json encode the values client
|
||||
// side due to them already being strings, which prevents gson from being able to convert them
|
||||
// to ints/floats/maps etc.
|
||||
return value.length() < MAX_VALUE_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean validateObject(JsonElement jsonElement, int depth)
|
||||
{
|
||||
if (depth >= MAX_DEPTH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jsonElement.isJsonObject())
|
||||
{
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet())
|
||||
{
|
||||
JsonElement element = entry.getValue();
|
||||
|
||||
if (!validateObject(element, depth + 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (jsonElement.isJsonArray())
|
||||
{
|
||||
JsonArray jsonArray = jsonElement.getAsJsonArray();
|
||||
|
||||
for (int i = 0; i < jsonArray.size(); ++i)
|
||||
{
|
||||
JsonElement element = jsonArray.get(i);
|
||||
|
||||
if (!validateObject(element, depth + 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (jsonElement.isJsonPrimitive())
|
||||
{
|
||||
JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();
|
||||
String value = jsonPrimitive.getAsString();
|
||||
if (value.length() >= MAX_VALUE_LENGTH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.feed.FeedItem;
|
||||
import net.runelite.http.api.feed.FeedResult;
|
||||
import net.runelite.http.service.feed.blog.BlogService;
|
||||
import net.runelite.http.service.feed.osrsnews.OSRSNewsService;
|
||||
import net.runelite.http.service.feed.twitter.TwitterService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/feed")
|
||||
@Slf4j
|
||||
public class FeedController
|
||||
{
|
||||
private final BlogService blogService;
|
||||
private final TwitterService twitterService;
|
||||
private final OSRSNewsService osrsNewsService;
|
||||
|
||||
private static class MemoizedFeed
|
||||
{
|
||||
final FeedResult feedResult;
|
||||
final String hash;
|
||||
|
||||
MemoizedFeed(FeedResult feedResult)
|
||||
{
|
||||
this.feedResult = feedResult;
|
||||
|
||||
Hasher hasher = Hashing.sha256().newHasher();
|
||||
for (FeedItem itemPrice : feedResult.getItems())
|
||||
{
|
||||
hasher.putBytes(itemPrice.getTitle().getBytes(StandardCharsets.UTF_8)).putBytes(itemPrice.getContent().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
HashCode code = hasher.hash();
|
||||
hash = code.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private MemoizedFeed memoizedFeed;
|
||||
|
||||
@Autowired
|
||||
public FeedController(BlogService blogService, TwitterService twitterService, OSRSNewsService osrsNewsService)
|
||||
{
|
||||
this.blogService = blogService;
|
||||
this.twitterService = twitterService;
|
||||
this.osrsNewsService = osrsNewsService;
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 10 * 60 * 1000)
|
||||
public void updateFeed()
|
||||
{
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
items.addAll(blogService.getBlogPosts());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("unable to fetch blogs", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
items.addAll(twitterService.getTweets());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("unable to fetch tweets", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
items.addAll(osrsNewsService.getNews());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("unable to fetch news", e);
|
||||
}
|
||||
|
||||
memoizedFeed = new MemoizedFeed(new FeedResult(items));
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<FeedResult> getFeed()
|
||||
{
|
||||
if (memoizedFeed == null)
|
||||
{
|
||||
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.cacheControl(CacheControl.noCache())
|
||||
.build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.eTag(memoizedFeed.hash)
|
||||
.cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic())
|
||||
.body(memoizedFeed.feedResult);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.blog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import net.runelite.http.api.feed.FeedItem;
|
||||
import net.runelite.http.api.feed.FeedItemType;
|
||||
import net.runelite.http.service.util.exception.InternalServerErrorException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@Service
|
||||
public class BlogService
|
||||
{
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl rssUrl;
|
||||
|
||||
@Autowired
|
||||
public BlogService(
|
||||
OkHttpClient okHttpClient,
|
||||
@Value("${runelite.feed.rssUrl}") String rssUrl
|
||||
)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.rssUrl = HttpUrl.get(rssUrl);
|
||||
}
|
||||
|
||||
public List<FeedItem> getBlogPosts() throws IOException
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url(rssUrl)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Error getting blog posts: " + response);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
Document document = DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder()
|
||||
.parse(in);
|
||||
|
||||
Element documentElement = document.getDocumentElement();
|
||||
NodeList documentItems = documentElement.getElementsByTagName("entry");
|
||||
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < Math.min(documentItems.getLength(), 3); i++)
|
||||
{
|
||||
Node item = documentItems.item(i);
|
||||
NodeList children = item.getChildNodes();
|
||||
|
||||
String title = null;
|
||||
String summary = null;
|
||||
String link = null;
|
||||
long timestamp = -1;
|
||||
|
||||
for (int j = 0; j < children.getLength(); j++)
|
||||
{
|
||||
Node childItem = children.item(j);
|
||||
String nodeName = childItem.getNodeName();
|
||||
|
||||
switch (nodeName)
|
||||
{
|
||||
case "title":
|
||||
title = childItem.getTextContent();
|
||||
break;
|
||||
case "summary":
|
||||
summary = childItem.getTextContent().replace("\n", "").trim();
|
||||
break;
|
||||
case "link":
|
||||
link = childItem.getAttributes().getNamedItem("href").getTextContent();
|
||||
break;
|
||||
case "updated":
|
||||
timestamp = DATE_FORMAT.parse(childItem.getTextContent()).getTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (title == null || summary == null || link == null || timestamp == -1)
|
||||
{
|
||||
throw new InternalServerErrorException("Failed to find title, summary, link and/or timestamp in the blog post feed");
|
||||
}
|
||||
|
||||
items.add(new FeedItem(FeedItemType.BLOG_POST, title, summary, link, timestamp));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
catch (ParserConfigurationException | SAXException | ParseException e)
|
||||
{
|
||||
throw new InternalServerErrorException("Failed to parse blog posts: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.osrsnews;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import net.runelite.http.api.feed.FeedItem;
|
||||
import net.runelite.http.api.feed.FeedItemType;
|
||||
import net.runelite.http.service.util.exception.InternalServerErrorException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@Service
|
||||
public class OSRSNewsService
|
||||
{
|
||||
private static final SimpleDateFormat PUB_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy '00:00:00 GMT'", Locale.US);
|
||||
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl rssUrl;
|
||||
|
||||
@Autowired
|
||||
public OSRSNewsService(
|
||||
OkHttpClient okHttpClient,
|
||||
@Value("${runelite.osrsnews.rssUrl}") String rssUrl
|
||||
)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.rssUrl = HttpUrl.get(rssUrl);
|
||||
}
|
||||
|
||||
public List<FeedItem> getNews() throws IOException
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url(rssUrl)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Error getting OSRS news: " + response);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
Document document = DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder()
|
||||
.parse(in);
|
||||
|
||||
Element documentElement = document.getDocumentElement();
|
||||
NodeList documentItems = documentElement.getElementsByTagName("item");
|
||||
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < documentItems.getLength(); i++)
|
||||
{
|
||||
Node item = documentItems.item(i);
|
||||
NodeList children = item.getChildNodes();
|
||||
|
||||
String title = null;
|
||||
String description = null;
|
||||
String link = null;
|
||||
long timestamp = -1;
|
||||
|
||||
for (int j = 0; j < children.getLength(); j++)
|
||||
{
|
||||
Node childItem = children.item(j);
|
||||
String nodeName = childItem.getNodeName();
|
||||
|
||||
switch (nodeName)
|
||||
{
|
||||
case "title":
|
||||
title = childItem.getTextContent();
|
||||
break;
|
||||
case "description":
|
||||
description = childItem.getTextContent().replace("\n", "").trim();
|
||||
break;
|
||||
case "link":
|
||||
link = childItem.getTextContent();
|
||||
break;
|
||||
case "pubDate":
|
||||
timestamp = PUB_DATE_FORMAT.parse(childItem.getTextContent()).getTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (title == null || description == null || link == null || timestamp == -1)
|
||||
{
|
||||
throw new InternalServerErrorException("Failed to find title, description, link and/or timestamp in the OSRS RSS feed");
|
||||
}
|
||||
|
||||
items.add(new FeedItem(FeedItemType.OSRS_NEWS, title, description, link, timestamp));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
catch (ParserConfigurationException | SAXException | ParseException e)
|
||||
{
|
||||
throw new InternalServerErrorException("Failed to parse OSRS news: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.twitter;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class TwitterOAuth2TokenResponse
|
||||
{
|
||||
@SerializedName("token_type")
|
||||
private String tokenType;
|
||||
|
||||
@SerializedName("access_token")
|
||||
private String token;
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.twitter;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.feed.FeedItem;
|
||||
import net.runelite.http.api.feed.FeedItemType;
|
||||
import net.runelite.http.service.util.exception.InternalServerErrorException;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class TwitterService
|
||||
{
|
||||
private static final HttpUrl AUTH_URL = HttpUrl.parse("https://api.twitter.com/oauth2/token");
|
||||
private static final HttpUrl LIST_STATUSES_URL = HttpUrl.parse("https://api.twitter.com/1.1/lists/statuses.json");
|
||||
|
||||
private final String credentials;
|
||||
private final String listId;
|
||||
private final OkHttpClient okHttpClient;
|
||||
|
||||
private String token;
|
||||
|
||||
@Autowired
|
||||
public TwitterService(
|
||||
@Value("${runelite.twitter.consumerkey}") String consumerKey,
|
||||
@Value("${runelite.twitter.secretkey}") String consumerSecret,
|
||||
@Value("${runelite.twitter.listid}") String listId,
|
||||
OkHttpClient okHttpClient
|
||||
)
|
||||
{
|
||||
this.credentials = consumerKey + ":" + consumerSecret;
|
||||
this.listId = listId;
|
||||
this.okHttpClient = okHttpClient;
|
||||
}
|
||||
|
||||
public List<FeedItem> getTweets() throws IOException
|
||||
{
|
||||
return getTweets(false);
|
||||
}
|
||||
|
||||
private List<FeedItem> getTweets(boolean hasRetried) throws IOException
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
updateToken();
|
||||
}
|
||||
|
||||
HttpUrl url = LIST_STATUSES_URL.newBuilder()
|
||||
.addQueryParameter("list_id", listId)
|
||||
.addQueryParameter("count", "15")
|
||||
.addQueryParameter("include_entities", "false")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
switch (HttpStatus.valueOf(response.code()))
|
||||
{
|
||||
case BAD_REQUEST:
|
||||
case UNAUTHORIZED:
|
||||
updateToken();
|
||||
if (!hasRetried)
|
||||
{
|
||||
return getTweets(true);
|
||||
}
|
||||
throw new InternalServerErrorException("Could not auth to Twitter after trying once: " + response);
|
||||
default:
|
||||
throw new IOException("Error getting Twitter list: " + response);
|
||||
}
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
Type listType = new TypeToken<List<TwitterStatusesResponseItem>>()
|
||||
{
|
||||
}.getType();
|
||||
List<TwitterStatusesResponseItem> statusesResponse = RuneLiteAPI.GSON
|
||||
.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), listType);
|
||||
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
|
||||
for (TwitterStatusesResponseItem i : statusesResponse)
|
||||
{
|
||||
items.add(new FeedItem(FeedItemType.TWEET,
|
||||
i.getUser().getProfileImageUrl(),
|
||||
i.getUser().getScreenName(),
|
||||
i.getText().replace("\n\n", " ").replaceAll("\n", " "),
|
||||
"https://twitter.com/" + i.getUser().getScreenName() + "/status/" + i.getId(),
|
||||
getTimestampFromSnowflake(i.getId())));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateToken() throws IOException
|
||||
{
|
||||
String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(AUTH_URL)
|
||||
.header("Authorization", "Basic " + encodedCredentials)
|
||||
.post(new FormBody.Builder().add("grant_type", "client_credentials").build())
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Error authing to Twitter: " + response);
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
TwitterOAuth2TokenResponse tokenResponse = RuneLiteAPI.GSON
|
||||
.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), TwitterOAuth2TokenResponse.class);
|
||||
|
||||
if (!tokenResponse.getTokenType().equals("bearer"))
|
||||
{
|
||||
throw new InternalServerErrorException("Returned token was not a bearer token");
|
||||
}
|
||||
|
||||
if (tokenResponse.getToken() == null)
|
||||
{
|
||||
throw new InternalServerErrorException("Returned token was null");
|
||||
}
|
||||
|
||||
token = tokenResponse.getToken();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the UTC timestamp from a Twitter snowflake as per
|
||||
* https://github.com/client9/snowflake2time/blob/master/python/snowflake.py#L24
|
||||
*/
|
||||
private long getTimestampFromSnowflake(long snowflake)
|
||||
{
|
||||
return (snowflake >> 22) + 1288834974657L;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.twitter;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class TwitterStatusesResponseItem
|
||||
{
|
||||
private long id;
|
||||
private String text;
|
||||
private TwitterStatusesResponseItemUser user;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.feed.twitter;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class TwitterStatusesResponseItemUser
|
||||
{
|
||||
@SerializedName("screen_name")
|
||||
private String screenName;
|
||||
|
||||
@SerializedName("profile_image_url_https")
|
||||
private String profileImageUrl;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.service.account.AuthFilter;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/ge")
|
||||
public class GrandExchangeController
|
||||
{
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final GrandExchangeService grandExchangeService;
|
||||
private final AuthFilter authFilter;
|
||||
private final RedisPool redisPool;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeController(GrandExchangeService grandExchangeService, AuthFilter authFilter, RedisPool redisPool)
|
||||
{
|
||||
this.grandExchangeService = grandExchangeService;
|
||||
this.authFilter = authFilter;
|
||||
this.redisPool = redisPool;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public void submit(HttpServletRequest request, HttpServletResponse response, @RequestBody GrandExchangeTrade grandExchangeTrade) throws IOException
|
||||
{
|
||||
SessionEntry session = null;
|
||||
if (request.getHeader(RuneLiteAPI.RUNELITE_AUTH) != null)
|
||||
{
|
||||
session = authFilter.handle(request, response);
|
||||
if (session == null)
|
||||
{
|
||||
// error is set here on the response, so we shouldn't continue
|
||||
return;
|
||||
}
|
||||
}
|
||||
Integer userId = session == null ? null : session.getUser();
|
||||
|
||||
// We don't keep track of pending trades in the web UI, so only add cancelled or completed trades
|
||||
if (userId != null &&
|
||||
grandExchangeTrade.getQty() > 0 &&
|
||||
(grandExchangeTrade.isCancel() || grandExchangeTrade.getQty() == grandExchangeTrade.getTotal()))
|
||||
{
|
||||
grandExchangeService.add(userId, grandExchangeTrade);
|
||||
}
|
||||
|
||||
Trade trade = new Trade();
|
||||
trade.setBuy(grandExchangeTrade.isBuy());
|
||||
trade.setCancel(grandExchangeTrade.isCancel());
|
||||
trade.setLogin(grandExchangeTrade.isLogin());
|
||||
trade.setItemId(grandExchangeTrade.getItemId());
|
||||
trade.setQty(grandExchangeTrade.getQty());
|
||||
trade.setDqty(grandExchangeTrade.getDqty());
|
||||
trade.setTotal(grandExchangeTrade.getTotal());
|
||||
trade.setSpent(grandExchangeTrade.getDspent());
|
||||
trade.setOffer(grandExchangeTrade.getOffer());
|
||||
trade.setSlot(grandExchangeTrade.getSlot());
|
||||
trade.setTime((int) (System.currentTimeMillis() / 1000L));
|
||||
trade.setMachineId(request.getHeader(RuneLiteAPI.RUNELITE_MACHINEID));
|
||||
trade.setUserId(userId);
|
||||
trade.setIp(request.getHeader("X-Forwarded-For"));
|
||||
trade.setUa(request.getHeader("User-Agent"));
|
||||
trade.setWorldType(grandExchangeTrade.getWorldType());
|
||||
trade.setSeq(grandExchangeTrade.getSeq());
|
||||
Instant resetTime = grandExchangeTrade.getResetTime();
|
||||
trade.setResetTime(resetTime == null ? 0L : resetTime.getEpochSecond());
|
||||
|
||||
String json = GSON.toJson(trade);
|
||||
try (Jedis jedis = redisPool.getResource())
|
||||
{
|
||||
jedis.publish("ge", json);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Collection<GrandExchangeTradeHistory> get(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam(required = false, defaultValue = "1024") int limit,
|
||||
@RequestParam(required = false, defaultValue = "0") int offset) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return grandExchangeService.get(session.getUser(), limit, offset).stream()
|
||||
.map(GrandExchangeController::convert)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static GrandExchangeTradeHistory convert(TradeEntry tradeEntry)
|
||||
{
|
||||
GrandExchangeTradeHistory grandExchangeTrade = new GrandExchangeTradeHistory();
|
||||
grandExchangeTrade.setBuy(tradeEntry.getAction() == TradeAction.BUY);
|
||||
grandExchangeTrade.setItemId(tradeEntry.getItem());
|
||||
grandExchangeTrade.setQuantity(tradeEntry.getQuantity());
|
||||
grandExchangeTrade.setPrice(tradeEntry.getPrice());
|
||||
grandExchangeTrade.setTime(tradeEntry.getTime());
|
||||
return grandExchangeTrade;
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
grandExchangeService.delete(session.getUser());
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.util.Collection;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
public class GrandExchangeService
|
||||
{
|
||||
private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS `ge_trades` (\n" +
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n" +
|
||||
" `user` int(11) NOT NULL,\n" +
|
||||
" `action` enum('BUY','SELL') NOT NULL,\n" +
|
||||
" `item` int(11) NOT NULL,\n" +
|
||||
" `quantity` int(11) NOT NULL,\n" +
|
||||
" `price` int(11) NOT NULL,\n" +
|
||||
" `time` timestamp NOT NULL DEFAULT current_timestamp(),\n" +
|
||||
" PRIMARY KEY (`id`),\n" +
|
||||
" KEY `user_time` (`user`, `time`),\n" +
|
||||
" KEY `time` (`time`),\n" +
|
||||
" CONSTRAINT `ge_trades_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`)\n" +
|
||||
") ENGINE=InnoDB;";
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final int historyDays;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeService(
|
||||
@Qualifier("Runelite SQL2O") Sql2o sql2o,
|
||||
@Value("${runelite.ge.history}") int historyDays
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.historyDays = historyDays;
|
||||
|
||||
// Ensure necessary tables exist
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE_TABLE).executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int userId, GrandExchangeTrade grandExchangeTrade)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("insert into ge_trades (user, action, item, quantity, price) values (:user," +
|
||||
" :action, :item, :quantity, :price)")
|
||||
.addParameter("user", userId)
|
||||
.addParameter("action", grandExchangeTrade.isBuy() ? "BUY" : "SELL")
|
||||
.addParameter("item", grandExchangeTrade.getItemId())
|
||||
.addParameter("quantity", grandExchangeTrade.getQty())
|
||||
.addParameter("price", grandExchangeTrade.getSpent() / grandExchangeTrade.getQty())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<TradeEntry> get(int userId, int limit, int offset)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
return con.createQuery("select id, user, action, item, quantity, price, time from ge_trades where user = :user limit :limit offset :offset")
|
||||
.addParameter("user", userId)
|
||||
.addParameter("limit", limit)
|
||||
.addParameter("offset", offset)
|
||||
.executeAndFetch(TradeEntry.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(int userId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from ge_trades where user = :user")
|
||||
.addParameter("user", userId)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 60 * 60 * 1000)
|
||||
public void expire()
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from ge_trades where time < current_timestamp - interval " + historyDays + " day")
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class GrandExchangeTradeHistory
|
||||
{
|
||||
private boolean buy;
|
||||
private int itemId;
|
||||
private int quantity;
|
||||
private int price;
|
||||
private Instant time;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.worlds.WorldType;
|
||||
|
||||
@Data
|
||||
class Trade
|
||||
{
|
||||
private boolean buy;
|
||||
private boolean cancel;
|
||||
private boolean login;
|
||||
private int itemId;
|
||||
private int qty;
|
||||
private int dqty;
|
||||
private int total;
|
||||
private int spent;
|
||||
private int offer;
|
||||
private int slot;
|
||||
private int time;
|
||||
private String machineId;
|
||||
private Integer userId;
|
||||
private String ip;
|
||||
private String ua;
|
||||
private WorldType worldType;
|
||||
private int seq;
|
||||
private long resetTime;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
enum TradeAction
|
||||
{
|
||||
BUY,
|
||||
SELL;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class TradeEntry
|
||||
{
|
||||
private int id;
|
||||
private int user;
|
||||
private TradeAction action;
|
||||
private int item;
|
||||
private int quantity;
|
||||
private int price;
|
||||
private Instant time;
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import net.runelite.http.api.item.ItemPrice;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/item")
|
||||
public class ItemController
|
||||
{
|
||||
private static class MemoizedPrices
|
||||
{
|
||||
final ItemPrice[] prices;
|
||||
final String hash;
|
||||
|
||||
MemoizedPrices(ItemPrice[] prices)
|
||||
{
|
||||
this.prices = prices;
|
||||
|
||||
Hasher hasher = Hashing.sha256().newHasher();
|
||||
for (ItemPrice itemPrice : prices)
|
||||
{
|
||||
hasher.putInt(itemPrice.getId()).putInt(itemPrice.getPrice());
|
||||
}
|
||||
HashCode code = hasher.hash();
|
||||
hash = code.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private final ItemService itemService;
|
||||
private final int priceCache;
|
||||
|
||||
private final Supplier<MemoizedPrices> memoizedPrices;
|
||||
|
||||
@Autowired
|
||||
public ItemController(
|
||||
ItemService itemService,
|
||||
@Value("${runelite.price.cache}") int priceCache
|
||||
)
|
||||
{
|
||||
this.itemService = itemService;
|
||||
this.priceCache = priceCache;
|
||||
|
||||
memoizedPrices = Suppliers.memoizeWithExpiration(() -> new MemoizedPrices(itemService.fetchPrices().stream()
|
||||
.map(priceEntry ->
|
||||
{
|
||||
ItemPrice itemPrice = new ItemPrice();
|
||||
itemPrice.setId(priceEntry.getItem());
|
||||
itemPrice.setName(priceEntry.getName());
|
||||
itemPrice.setPrice(priceEntry.getPrice());
|
||||
itemPrice.setWikiPrice(computeWikiPrice(priceEntry));
|
||||
return itemPrice;
|
||||
})
|
||||
.toArray(ItemPrice[]::new)), priceCache, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private static int computeWikiPrice(PriceEntry priceEntry)
|
||||
{
|
||||
if (priceEntry.getLow() > 0 && priceEntry.getHigh() > 0)
|
||||
{
|
||||
return (priceEntry.getLow() + priceEntry.getHigh()) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Math.max(priceEntry.getLow(), priceEntry.getHigh());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/prices")
|
||||
public ResponseEntity<ItemPrice[]> prices()
|
||||
{
|
||||
MemoizedPrices memorizedPrices = this.memoizedPrices.get();
|
||||
return ResponseEntity.ok()
|
||||
.eTag(memorizedPrices.hash)
|
||||
.cacheControl(CacheControl.maxAge(priceCache, TimeUnit.MINUTES).cachePublic())
|
||||
.body(memorizedPrices.prices);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.item.ItemType;
|
||||
|
||||
@Data
|
||||
public class ItemEntry
|
||||
{
|
||||
private int id;
|
||||
private String name;
|
||||
private String description;
|
||||
private ItemType type;
|
||||
private Instant timestamp;
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.cache.definitions.ItemDefinition;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.item.ItemType;
|
||||
import net.runelite.http.service.cache.CacheService;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ItemService
|
||||
{
|
||||
private static final String CREATE_ITEMS = "CREATE TABLE IF NOT EXISTS `items` (\n"
|
||||
+ " `id` int(11) NOT NULL,\n"
|
||||
+ " `name` tinytext NOT NULL,\n"
|
||||
+ " `description` tinytext NOT NULL,\n"
|
||||
+ " `type` enum('DEFAULT') NOT NULL,\n"
|
||||
+ " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
|
||||
+ " PRIMARY KEY (`id`)\n"
|
||||
+ ") ENGINE=InnoDB";
|
||||
|
||||
private static final String CREATE_PRICES = "CREATE TABLE IF NOT EXISTS `prices` (\n"
|
||||
+ " `item` int(11) NOT NULL,\n"
|
||||
+ " `price` int(11) NOT NULL,\n"
|
||||
+ " `time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
|
||||
+ " `fetched_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
|
||||
+ " UNIQUE KEY `item_time` (`item`,`time`),\n"
|
||||
+ " KEY `item_fetched_time` (`item`,`fetched_time`)\n"
|
||||
+ ") ENGINE=InnoDB";
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final CacheService cacheService;
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl itemUrl;
|
||||
private final HttpUrl priceUrl;
|
||||
|
||||
private int[] tradeableItems;
|
||||
private final Random random = new Random();
|
||||
|
||||
@Autowired
|
||||
public ItemService(
|
||||
@Qualifier("Runelite SQL2O") Sql2o sql2o,
|
||||
CacheService cacheService,
|
||||
OkHttpClient okHttpClient,
|
||||
@Value("${runelite.item.itemUrl}") String itemUrl,
|
||||
@Value("${runelite.item.priceUrl}") String priceUrl
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.cacheService = cacheService;
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.itemUrl = HttpUrl.get(itemUrl);
|
||||
this.priceUrl = HttpUrl.get(priceUrl);
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE_ITEMS)
|
||||
.executeUpdate();
|
||||
|
||||
con.createQuery(CREATE_PRICES)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public ItemEntry getItem(int itemId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
return con.createQuery("select id, name, description, type from items where id = :id")
|
||||
.addParameter("id", itemId)
|
||||
.executeAndFetchFirst(ItemEntry.class);
|
||||
}
|
||||
}
|
||||
|
||||
public ItemEntry fetchItem(int itemId)
|
||||
{
|
||||
try
|
||||
{
|
||||
RSItem rsItem = fetchRSItem(itemId);
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("insert into items (id, name, description, type) values (:id,"
|
||||
+ " :name, :description, :type) ON DUPLICATE KEY UPDATE name = :name,"
|
||||
+ " description = :description, type = :type")
|
||||
.addParameter("id", rsItem.getId())
|
||||
.addParameter("name", rsItem.getName())
|
||||
.addParameter("description", rsItem.getDescription())
|
||||
.addParameter("type", rsItem.getType())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
ItemEntry item = new ItemEntry();
|
||||
item.setId(itemId);
|
||||
item.setName(rsItem.getName());
|
||||
item.setDescription(rsItem.getDescription());
|
||||
item.setType(ItemType.of(rsItem.getType()));
|
||||
return item;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to fetch item {}", itemId, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchPrice(int itemId)
|
||||
{
|
||||
RSPrices rsprice;
|
||||
try
|
||||
{
|
||||
rsprice = fetchRSPrices(itemId);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to fetch price for item {}", itemId, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection con = sql2o.beginTransaction())
|
||||
{
|
||||
Instant now = Instant.now();
|
||||
|
||||
Query query = con.createQuery("insert into prices (item, price, time, fetched_time) values (:item, :price, :time, :fetched_time) "
|
||||
+ "ON DUPLICATE KEY UPDATE price = VALUES(price), fetched_time = VALUES(fetched_time)");
|
||||
|
||||
for (Map.Entry<Long, Integer> entry : rsprice.getDaily().entrySet())
|
||||
{
|
||||
long ts = entry.getKey(); // ms since epoch
|
||||
int price = entry.getValue(); // gp
|
||||
|
||||
Instant time = Instant.ofEpochMilli(ts);
|
||||
|
||||
query
|
||||
.addParameter("item", itemId)
|
||||
.addParameter("price", price)
|
||||
.addParameter("time", time)
|
||||
.addParameter("fetched_time", now)
|
||||
.addToBatch();
|
||||
}
|
||||
|
||||
query.executeBatch();
|
||||
con.commit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public List<PriceEntry> fetchPrices()
|
||||
{
|
||||
try (Connection con = sql2o.beginTransaction())
|
||||
{
|
||||
Query query = con.createQuery("select t2.item, t3.name, t2.time, prices.price, prices.fetched_time, t4.high, t4.low" +
|
||||
" from (select t1.item as item, max(t1.time) as time from prices t1 group by item) t2" +
|
||||
" join prices on t2.item=prices.item and t2.time=prices.time" +
|
||||
" join items t3 on t2.item=t3.id" +
|
||||
" join wiki_prices t4 on t2.item=t4.item_id");
|
||||
return query.executeAndFetch(PriceEntry.class);
|
||||
}
|
||||
}
|
||||
|
||||
private RSItem fetchRSItem(int itemId) throws IOException
|
||||
{
|
||||
HttpUrl itemUrl = this.itemUrl
|
||||
.newBuilder()
|
||||
.addQueryParameter("item", "" + itemId)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(itemUrl)
|
||||
.build();
|
||||
|
||||
RSItemResponse itemResponse = fetchJson(request, RSItemResponse.class);
|
||||
return itemResponse.getItem();
|
||||
|
||||
}
|
||||
|
||||
private RSPrices fetchRSPrices(int itemId) throws IOException
|
||||
{
|
||||
HttpUrl priceUrl = this.priceUrl
|
||||
.newBuilder()
|
||||
.addPathSegment(itemId + ".json")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(priceUrl)
|
||||
.build();
|
||||
|
||||
return fetchJson(request, RSPrices.class);
|
||||
}
|
||||
|
||||
private <T> T fetchJson(Request request, Class<T> clazz) throws IOException
|
||||
{
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unsuccessful http response: " + response);
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), clazz);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 20_000)
|
||||
public void crawlPrices()
|
||||
{
|
||||
if (tradeableItems == null || tradeableItems.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = random.nextInt(tradeableItems.length);
|
||||
int id = tradeableItems[idx];
|
||||
|
||||
log.debug("Fetching price for {}", id);
|
||||
|
||||
// check if the item name or description has changed
|
||||
fetchItem(id);
|
||||
fetchPrice(id);
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 1_800_000) // 30 minutes
|
||||
public void reloadItems() throws IOException
|
||||
{
|
||||
List<ItemDefinition> items = cacheService.getItems();
|
||||
if (items.isEmpty())
|
||||
{
|
||||
log.warn("Failed to load any items from cache, item price updating will be disabled");
|
||||
}
|
||||
|
||||
tradeableItems = items.stream()
|
||||
.filter(ItemDefinition::isTradeable)
|
||||
.mapToInt(ItemDefinition::getId)
|
||||
.toArray();
|
||||
|
||||
log.debug("Loaded {} tradeable items", tradeableItems.length);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class PriceEntry
|
||||
{
|
||||
private int item;
|
||||
private String name;
|
||||
private int price;
|
||||
private Instant time;
|
||||
private Instant fetched_time;
|
||||
private int high;
|
||||
private int low;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class RSItem
|
||||
{
|
||||
private int id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String type;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class RSItemResponse
|
||||
{
|
||||
private RSItem item;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.item;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RSPrices
|
||||
{
|
||||
/**
|
||||
* unix time in ms to price in gp
|
||||
*/
|
||||
private Map<Long, Integer> daily;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.loottracker;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
import net.runelite.http.api.loottracker.LootRecordType;
|
||||
|
||||
@Data
|
||||
class LootResult
|
||||
{
|
||||
private int killId;
|
||||
private Instant first_time;
|
||||
private Instant last_time;
|
||||
private LootRecordType type;
|
||||
private String eventId;
|
||||
private int amount;
|
||||
private int itemId;
|
||||
private int itemQuantity;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.loottracker;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.loottracker.LootAggregate;
|
||||
import net.runelite.http.api.loottracker.LootRecord;
|
||||
import net.runelite.http.service.account.AuthFilter;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/loottracker")
|
||||
public class LootTrackerController
|
||||
{
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
@Autowired
|
||||
private LootTrackerService service;
|
||||
|
||||
@Autowired
|
||||
private RedisPool redisPool;
|
||||
|
||||
@Autowired
|
||||
private AuthFilter auth;
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public void storeLootRecord(HttpServletRequest request, HttpServletResponse response, @RequestBody Collection<LootRecord> records) throws IOException
|
||||
{
|
||||
SessionEntry session = null;
|
||||
if (request.getHeader(RuneLiteAPI.RUNELITE_AUTH) != null)
|
||||
{
|
||||
session = auth.handle(request, response);
|
||||
if (session == null)
|
||||
{
|
||||
// error is set here on the response, so we shouldn't continue
|
||||
return;
|
||||
}
|
||||
}
|
||||
Integer userId = session == null ? null : session.getUser();
|
||||
|
||||
if (userId != null)
|
||||
{
|
||||
service.store(records, userId);
|
||||
}
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
|
||||
try (Jedis jedis = redisPool.getResource())
|
||||
{
|
||||
jedis.publish("drops", GSON.toJson(records));
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Collection<LootAggregate> getLootAggregate(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "count", defaultValue = "1024") int count, @RequestParam(value = "start", defaultValue = "0") int start) throws IOException
|
||||
{
|
||||
SessionEntry e = auth.handle(request, response);
|
||||
if (e == null)
|
||||
{
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
return null;
|
||||
}
|
||||
|
||||
return service.get(e.getUser(), count, start);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
public void deleteLoot(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam(required = false) String eventId) throws IOException
|
||||
{
|
||||
SessionEntry e = auth.handle(request, response);
|
||||
if (e == null)
|
||||
{
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
service.delete(e.getUser(), eventId);
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.loottracker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.http.api.loottracker.GameItem;
|
||||
import net.runelite.http.api.loottracker.LootAggregate;
|
||||
import net.runelite.http.api.loottracker.LootRecord;
|
||||
import net.runelite.http.api.loottracker.LootRecordType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
public class LootTrackerService
|
||||
{
|
||||
private static final String CREATE_KILLS = "CREATE TABLE IF NOT EXISTS `loottracker_kills` (\n" +
|
||||
" `id` bigint NOT NULL AUTO_INCREMENT,\n" +
|
||||
" `first_time` timestamp NOT NULL DEFAULT current_timestamp(),\n" +
|
||||
" `last_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\n" +
|
||||
" `accountId` int(11) NOT NULL,\n" +
|
||||
" `type` enum('NPC','PLAYER','EVENT','PICKPOCKET','UNKNOWN') NOT NULL,\n" +
|
||||
" `eventId` varchar(255) NOT NULL,\n" +
|
||||
" `amount` int(11) NOT NULL,\n" +
|
||||
" PRIMARY KEY (`id`),\n" +
|
||||
" FOREIGN KEY (accountId) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE,\n" +
|
||||
" INDEX idx_acc_lasttime (`accountId` ,`last_time`),\n" +
|
||||
" UNIQUE INDEX idx_acc_type_event (`accountId`, `type`, `eventId`),\n" +
|
||||
" INDEX idx_time (last_time)" +
|
||||
") ENGINE=InnoDB;";
|
||||
|
||||
private static final String CREATE_DROPS = "CREATE TABLE IF NOT EXISTS `loottracker_drops` (\n" +
|
||||
" `killId` bigint NOT NULL,\n" +
|
||||
" `itemId` int(11) NOT NULL,\n" +
|
||||
" `itemQuantity` int(11) NOT NULL,\n" +
|
||||
" UNIQUE INDEX idx_kill_item (`killId`, `itemId`),\n" +
|
||||
" FOREIGN KEY (killId) REFERENCES loottracker_kills(id) ON DELETE CASCADE\n" +
|
||||
") ENGINE=InnoDB;\n";
|
||||
|
||||
// Queries for inserting kills
|
||||
private static final String INSERT_KILL_QUERY = "INSERT INTO loottracker_kills (accountId, type, eventId, amount) VALUES (:accountId, :type, :eventId, :kills) ON DUPLICATE KEY UPDATE amount = amount + :kills";
|
||||
private static final String INSERT_DROP_QUERY = "INSERT INTO loottracker_drops (killId, itemId, itemQuantity) VALUES (:killId, :itemId, :itemQuantity) ON DUPLICATE KEY UPDATE itemQuantity = itemQuantity + :itemQuantity";
|
||||
|
||||
private static final String SELECT_LOOT_QUERY = "SELECT killId,first_time,last_time,type,eventId,amount,itemId,itemQuantity FROM loottracker_kills JOIN loottracker_drops ON loottracker_drops.killId = loottracker_kills.id WHERE accountId = :accountId ORDER BY last_time DESC LIMIT :limit OFFSET :offset";
|
||||
|
||||
private static final String DELETE_LOOT_ACCOUNT = "DELETE FROM loottracker_kills WHERE accountId = :accountId";
|
||||
private static final String DELETE_LOOT_ACCOUNT_EVENTID = "DELETE FROM loottracker_kills WHERE accountId = :accountId AND eventId = :eventId";
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final int historyDays;
|
||||
|
||||
@Autowired
|
||||
public LootTrackerService(
|
||||
@Qualifier("Runelite SQL2O") Sql2o sql2o,
|
||||
@Value("${runelite.loottracker.history}") int historyDays
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.historyDays = historyDays;
|
||||
|
||||
// Ensure necessary tables exist
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE_KILLS).executeUpdate();
|
||||
con.createQuery(CREATE_DROPS).executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode(exclude = {"kills", "drops"})
|
||||
@Getter
|
||||
private static class AggregateLootRecord
|
||||
{
|
||||
final LootRecordType type;
|
||||
final String eventId;
|
||||
int kills = 0;
|
||||
Map<AggregateDrop, AggregateDrop> drops = new HashMap<>();
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode(exclude = "qty")
|
||||
@Getter
|
||||
private static class AggregateDrop
|
||||
{
|
||||
final int id;
|
||||
int qty = 0;
|
||||
}
|
||||
|
||||
private static Collection<AggregateLootRecord> aggregate(Collection<LootRecord> records)
|
||||
{
|
||||
Map<AggregateLootRecord, AggregateLootRecord> combinedRecords = new HashMap<>();
|
||||
for (LootRecord record : records)
|
||||
{
|
||||
AggregateLootRecord r = new AggregateLootRecord(record.getType(), record.getEventId());
|
||||
r = combinedRecords.computeIfAbsent(r, (k) -> k);
|
||||
++r.kills;
|
||||
|
||||
// Combine drops
|
||||
for (GameItem gameItem : record.getDrops())
|
||||
{
|
||||
AggregateDrop cd = new AggregateDrop(gameItem.getId());
|
||||
cd = r.drops.computeIfAbsent(cd, (k) -> k);
|
||||
cd.qty += gameItem.getQty();
|
||||
}
|
||||
}
|
||||
return combinedRecords.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store LootRecord
|
||||
*
|
||||
* @param records LootRecords to store
|
||||
* @param accountId runelite account id to tie data too
|
||||
*/
|
||||
public void store(Collection<LootRecord> records, int accountId)
|
||||
{
|
||||
Collection<AggregateLootRecord> combinedRecords = aggregate(records);
|
||||
|
||||
try (Connection con = sql2o.beginTransaction())
|
||||
{
|
||||
Query killQuery = con.createQuery(INSERT_KILL_QUERY, true);
|
||||
Query insertDrop = con.createQuery(INSERT_DROP_QUERY);
|
||||
|
||||
for (AggregateLootRecord record : combinedRecords)
|
||||
{
|
||||
killQuery
|
||||
.addParameter("accountId", accountId)
|
||||
.addParameter("type", record.getType())
|
||||
.addParameter("eventId", record.getEventId())
|
||||
.addParameter("kills", record.getKills())
|
||||
.executeUpdate();
|
||||
Object[] keys = con.getKeys();
|
||||
|
||||
for (AggregateDrop drop : record.getDrops().values())
|
||||
{
|
||||
insertDrop
|
||||
.addParameter("killId", keys[0])
|
||||
.addParameter("itemId", drop.getId())
|
||||
.addParameter("itemQuantity", drop.getQty())
|
||||
.addToBatch();
|
||||
}
|
||||
|
||||
insertDrop.executeBatch();
|
||||
}
|
||||
|
||||
con.commit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<LootAggregate> get(int accountId, int limit, int offset)
|
||||
{
|
||||
List<LootResult> lootResults;
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
lootResults = con.createQuery(SELECT_LOOT_QUERY)
|
||||
.addParameter("accountId", accountId)
|
||||
.addParameter("limit", limit)
|
||||
.addParameter("offset", offset)
|
||||
.executeAndFetch(LootResult.class);
|
||||
}
|
||||
|
||||
LootResult current = null;
|
||||
List<LootAggregate> lootRecords = new ArrayList<>();
|
||||
List<GameItem> gameItems = new ArrayList<>();
|
||||
|
||||
for (LootResult lootResult : lootResults)
|
||||
{
|
||||
if (current == null || current.getKillId() != lootResult.getKillId())
|
||||
{
|
||||
if (!gameItems.isEmpty())
|
||||
{
|
||||
LootAggregate lootRecord = new LootAggregate(current.getEventId(), current.getType(), gameItems, current.getFirst_time(), current.getLast_time(), current.getAmount());
|
||||
lootRecords.add(lootRecord);
|
||||
|
||||
gameItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
current = lootResult;
|
||||
}
|
||||
|
||||
GameItem gameItem = new GameItem(lootResult.getItemId(), lootResult.getItemQuantity());
|
||||
gameItems.add(gameItem);
|
||||
}
|
||||
|
||||
if (!gameItems.isEmpty())
|
||||
{
|
||||
LootAggregate lootRecord = new LootAggregate(current.getEventId(), current.getType(), gameItems, current.getFirst_time(), current.getLast_time(), current.getAmount());
|
||||
lootRecords.add(lootRecord);
|
||||
}
|
||||
|
||||
return lootRecords;
|
||||
}
|
||||
|
||||
public void delete(int accountId, String eventId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
if (eventId == null)
|
||||
{
|
||||
con.createQuery(DELETE_LOOT_ACCOUNT)
|
||||
.addParameter("accountId", accountId)
|
||||
.executeUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
con.createQuery(DELETE_LOOT_ACCOUNT_EVENTID)
|
||||
.addParameter("accountId", accountId)
|
||||
.addParameter("eventId", eventId)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 60 * 60 * 1000)
|
||||
public void expire()
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from loottracker_kills where last_time < current_timestamp() - interval " + historyDays + " day")
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.pluginhub;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/pluginhub")
|
||||
public class PluginHubController
|
||||
{
|
||||
@Value("${pluginhub.stats.days:7}")
|
||||
private int days;
|
||||
|
||||
@Value("${pluginhub.stats.expire:90}")
|
||||
private int expireDays;
|
||||
|
||||
@Autowired
|
||||
private RedisPool redisPool;
|
||||
|
||||
private final Cache<String, String> pluginCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(512L)
|
||||
.build();
|
||||
|
||||
private Map<String, Long> pluginCounts = Collections.emptyMap();
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Map<String, Long>> get()
|
||||
{
|
||||
if (pluginCounts.isEmpty())
|
||||
{
|
||||
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.cacheControl(CacheControl.noCache())
|
||||
.build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.cacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES).cachePublic())
|
||||
.body(pluginCounts);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public void submit(HttpServletRequest request, @RequestBody String[] plugins)
|
||||
{
|
||||
final String date = Instant.now().atZone(ZoneOffset.UTC).format(DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
final String ip = request.getHeader("X-Forwarded-For");
|
||||
try (Jedis jedis = redisPool.getResource())
|
||||
{
|
||||
for (String plugin : plugins)
|
||||
{
|
||||
if (!plugin.matches("[a-z0-9-]+"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
jedis.pfadd("pluginhub." + plugin + "." + date, ip);
|
||||
|
||||
if (pluginCache.getIfPresent(plugin) == null)
|
||||
{
|
||||
jedis.sadd("pluginhub.plugins", plugin);
|
||||
// additionally set the ttl on the hyperloglog since it might be a new key
|
||||
jedis.expire("pluginhub." + plugin + "." + date, (int) (Duration.ofDays(expireDays).toMillis() / 1000L));
|
||||
|
||||
pluginCache.put(plugin, plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 1_800_000, initialDelay = 30_000) // 30 minutes with 30 second initial delay
|
||||
public void rebuildCounts()
|
||||
{
|
||||
Map<String, Long> counts = new HashMap<>();
|
||||
try (Jedis jedis = redisPool.getResource())
|
||||
{
|
||||
Set<String> plugins = jedis.smembers("pluginhub.plugins");
|
||||
ZonedDateTime time = Instant.now().atZone(ZoneOffset.UTC);
|
||||
|
||||
for (String plugin : plugins)
|
||||
{
|
||||
// When called with multiple keys, pfcount returns the approximated
|
||||
// cardinality of the union of the HyperLogLogs. We use this to determine
|
||||
// the number of users in the last N days.
|
||||
String[] keys = IntStream.range(0, days - 1)
|
||||
.mapToObj(time::minusDays)
|
||||
.map(zdt -> "pluginhub." + plugin + "." + zdt.format(DateTimeFormatter.ISO_LOCAL_DATE))
|
||||
.toArray(String[]::new);
|
||||
long cnt = jedis.pfcount(keys);
|
||||
if (cnt > 0)
|
||||
{
|
||||
counts.put(plugin, cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
pluginCounts = counts;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.util;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import org.sql2o.converters.Converter;
|
||||
import org.sql2o.converters.ConverterException;
|
||||
|
||||
public class InstantConverter implements Converter<Instant>
|
||||
{
|
||||
@Override
|
||||
public Instant convert(Object val) throws ConverterException
|
||||
{
|
||||
Timestamp ts = (Timestamp) val;
|
||||
return ts.toInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toDatabaseParam(Instant val)
|
||||
{
|
||||
return Timestamp.from(val);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.util.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public class InternalServerErrorException extends RuntimeException
|
||||
{
|
||||
public InternalServerErrorException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.util.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Not found")
|
||||
public class NotFoundException extends RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.util.redis;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RedisPool
|
||||
{
|
||||
private final String redisHost;
|
||||
private final BlockingQueue<Jedis> queue;
|
||||
|
||||
RedisPool(@Value("${redis.pool.size:10}") int queueSize, @Value("${redis.host:localhost}") String redisHost)
|
||||
{
|
||||
this.redisHost = redisHost;
|
||||
|
||||
queue = new ArrayBlockingQueue<>(queueSize);
|
||||
for (int i = 0; i < queueSize; ++i)
|
||||
{
|
||||
Jedis jedis = new PooledJedis(redisHost);
|
||||
queue.offer(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
public Jedis getResource()
|
||||
{
|
||||
Jedis jedis;
|
||||
try
|
||||
{
|
||||
jedis = queue.poll(1, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (jedis == null)
|
||||
{
|
||||
throw new RuntimeException("Unable to acquire connection from pool, timeout");
|
||||
}
|
||||
return jedis;
|
||||
}
|
||||
|
||||
class PooledJedis extends Jedis
|
||||
{
|
||||
PooledJedis(String host)
|
||||
{
|
||||
super(host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
if (!getClient().isBroken())
|
||||
{
|
||||
queue.offer(this);
|
||||
return;
|
||||
}
|
||||
|
||||
log.warn("jedis client is broken, creating new client");
|
||||
|
||||
try
|
||||
{
|
||||
super.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("unable to close broken jedis", e);
|
||||
}
|
||||
|
||||
queue.offer(new PooledJedis(redisHost));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.wiki;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class PriceResult
|
||||
{
|
||||
@Data
|
||||
static class Item
|
||||
{
|
||||
private int high;
|
||||
private int highTime;
|
||||
private int low;
|
||||
private int lowTime;
|
||||
}
|
||||
|
||||
private Map<Integer, Item> data;
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.wiki;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WikiPriceService
|
||||
{
|
||||
private static final String CREATE = "CREATE TABLE IF NOT EXISTS `wiki_prices` (\n" +
|
||||
" `item_id` int(11) NOT NULL,\n" +
|
||||
" `high` int(11) NOT NULL,\n" +
|
||||
" `highTime` int(11) NOT NULL,\n" +
|
||||
" `low` int(11) NOT NULL,\n" +
|
||||
" `lowTime` int(11) NOT NULL,\n" +
|
||||
" `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" +
|
||||
" PRIMARY KEY (`item_id`)\n" +
|
||||
") ENGINE=InnoDB;";
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl wikiUrl;
|
||||
|
||||
@Autowired
|
||||
public WikiPriceService(
|
||||
@Qualifier("Runelite SQL2O") Sql2o sql2o,
|
||||
OkHttpClient okHttpClient,
|
||||
@Value("${runelite.wiki.url}") String url
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.wikiUrl = HttpUrl.get(url);
|
||||
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE).executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(initialDelay = 1000 * 5, fixedDelayString = "${runelite.wiki.poll.ms}")
|
||||
private void updateDatabase()
|
||||
{
|
||||
try
|
||||
{
|
||||
PriceResult summary = getPrices();
|
||||
|
||||
try (Connection con = sql2o.beginTransaction())
|
||||
{
|
||||
Query query = con.createQuery("INSERT INTO wiki_prices (item_id, high, highTime, low, lowTime)"
|
||||
+ " VALUES (:itemId, :high, :highTime, :low, :lowTime)"
|
||||
+ " ON DUPLICATE KEY UPDATE high = VALUES(high), highTime = VALUES(highTime),"
|
||||
+ " low = VALUES(low), lowTime = VALUES(lowTime)");
|
||||
|
||||
for (Map.Entry<Integer, PriceResult.Item> entry : summary.getData().entrySet())
|
||||
{
|
||||
Integer itemId = entry.getKey();
|
||||
PriceResult.Item item = entry.getValue();
|
||||
|
||||
query
|
||||
.addParameter("itemId", itemId)
|
||||
.addParameter("high", item.getHigh())
|
||||
.addParameter("highTime", item.getHighTime())
|
||||
.addParameter("low", item.getLow())
|
||||
.addParameter("lowTime", item.getLowTime())
|
||||
.addToBatch();
|
||||
}
|
||||
|
||||
query.executeBatch();
|
||||
con.commit(false);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Error while updating wiki prices", e);
|
||||
}
|
||||
}
|
||||
|
||||
private PriceResult getPrices() throws IOException
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url(wikiUrl)
|
||||
.header("User-Agent", "RuneLite")
|
||||
.build();
|
||||
|
||||
try (Response responseOk = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!responseOk.isSuccessful())
|
||||
{
|
||||
throw new IOException("Error retrieving prices: " + responseOk.message());
|
||||
}
|
||||
|
||||
return RuneLiteAPI.GSON.fromJson(responseOk.body().string(), PriceResult.class);
|
||||
}
|
||||
catch (JsonSyntaxException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.worlds;
|
||||
|
||||
import net.runelite.http.api.worlds.WorldType;
|
||||
|
||||
enum ServiceWorldType
|
||||
{
|
||||
MEMBERS(WorldType.MEMBERS, 1),
|
||||
PVP(WorldType.PVP, 1 << 2),
|
||||
BOUNTY(WorldType.BOUNTY, 1 << 5),
|
||||
SKILL_TOTAL(WorldType.SKILL_TOTAL, 1 << 7),
|
||||
HIGH_RISK(WorldType.HIGH_RISK, 1 << 10),
|
||||
LAST_MAN_STANDING(WorldType.LAST_MAN_STANDING, 1 << 14),
|
||||
NOSAVE_MODE(WorldType.NOSAVE_MODE, 1 << 25),
|
||||
TOURNAMENT(WorldType.TOURNAMENT, 1 << 26),
|
||||
DEADMAN(WorldType.DEADMAN, 1 << 29),
|
||||
SEASONAL(WorldType.SEASONAL, 1 << 30);
|
||||
|
||||
private final WorldType apiType;
|
||||
private final int mask;
|
||||
|
||||
ServiceWorldType(WorldType apiType, int mask)
|
||||
{
|
||||
this.apiType = apiType;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public WorldType getApiType()
|
||||
{
|
||||
return apiType;
|
||||
}
|
||||
|
||||
public int getMask()
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.worlds;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/worlds")
|
||||
public class WorldController
|
||||
{
|
||||
@Autowired
|
||||
private WorldsService worldsService;
|
||||
|
||||
private WorldResult worldResult;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<WorldResult> listWorlds()
|
||||
{
|
||||
if (worldResult == null)
|
||||
{
|
||||
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.cacheControl(CacheControl.noCache())
|
||||
.build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic())
|
||||
.body(worldResult);
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 60_000L)
|
||||
public void refreshWorlds() throws IOException
|
||||
{
|
||||
worldResult = worldsService.getWorlds();
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.worlds;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import net.runelite.http.api.worlds.WorldType;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WorldsService
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl url;
|
||||
|
||||
@Autowired
|
||||
public WorldsService(
|
||||
OkHttpClient okHttpClient,
|
||||
@Value("${runelite.worlds.url}") String url
|
||||
)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.url = HttpUrl.get(url);
|
||||
}
|
||||
|
||||
public WorldResult getWorlds() throws IOException
|
||||
{
|
||||
Request okrequest = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
byte[] b;
|
||||
|
||||
try (Response okresponse = okHttpClient.newCall(okrequest).execute())
|
||||
{
|
||||
b = okresponse.body().bytes();
|
||||
}
|
||||
|
||||
List<World> worlds = new ArrayList<>();
|
||||
ByteBuffer buf = ByteBuffer.wrap(b);
|
||||
|
||||
int length = buf.getInt();
|
||||
buf.limit(length + 4);
|
||||
|
||||
int num = buf.getShort() & 0xFFFF;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
final World.WorldBuilder worldBuilder = World.builder()
|
||||
.id(buf.getShort() & 0xFFFF)
|
||||
.types(getTypes(buf.getInt()))
|
||||
.address(readString(buf))
|
||||
.activity(readString(buf))
|
||||
.location(buf.get() & 0xFF)
|
||||
.players(buf.getShort());
|
||||
|
||||
worlds.add(worldBuilder.build());
|
||||
}
|
||||
|
||||
WorldResult result = new WorldResult();
|
||||
result.setWorlds(worlds);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static EnumSet<WorldType> getTypes(int mask)
|
||||
{
|
||||
EnumSet<WorldType> types = EnumSet.noneOf(WorldType.class);
|
||||
|
||||
for (ServiceWorldType type : ServiceWorldType.values())
|
||||
{
|
||||
if ((mask & type.getMask()) != 0)
|
||||
{
|
||||
types.add(type.getApiType());
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
private static String readString(ByteBuffer buf)
|
||||
{
|
||||
byte b;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
b = buf.get();
|
||||
|
||||
if (b == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sb.append((char) b);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.xtea;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
class XteaCache
|
||||
{
|
||||
private int region;
|
||||
private int key1;
|
||||
private int key2;
|
||||
private int key3;
|
||||
private int key4;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user