Partial 7.0 merge - API preview
This commit is contained in:
@@ -4,13 +4,14 @@ import arc.*;
|
||||
import arc.Files.*;
|
||||
import arc.backend.sdl.*;
|
||||
import arc.backend.sdl.jni.*;
|
||||
import arc.discord.*;
|
||||
import arc.discord.DiscordRPC.*;
|
||||
import arc.files.*;
|
||||
import arc.func.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.serialization.*;
|
||||
import club.minnced.discord.rpc.*;
|
||||
import com.codedisaster.steamworks.*;
|
||||
import mindustry.*;
|
||||
import mindustry.core.*;
|
||||
@@ -19,6 +20,7 @@ import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.net.*;
|
||||
import mindustry.net.Net.*;
|
||||
import mindustry.service.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -26,8 +28,8 @@ import java.io.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class DesktopLauncher extends ClientLauncher{
|
||||
public final static String discordID = "610508934456934412";
|
||||
boolean useDiscord = OS.is64Bit && !OS.isARM && !OS.hasProp("nodiscord"), loadError = false;
|
||||
public final static long discordID = 610508934456934412L;
|
||||
boolean useDiscord = !OS.hasProp("nodiscord"), loadError = false;
|
||||
Throwable steamError;
|
||||
|
||||
public static void main(String[] arg){
|
||||
@@ -38,6 +40,10 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
maximized = true;
|
||||
width = 900;
|
||||
height = 700;
|
||||
//enable gl3 with command-line argument
|
||||
if(Structs.contains(arg, "-gl3")){
|
||||
gl30 = true;
|
||||
}
|
||||
setWindowIcon(FileType.internal, "icons/icon_64.png");
|
||||
}});
|
||||
}catch(Throwable e){
|
||||
@@ -52,13 +58,15 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
|
||||
if(useDiscord){
|
||||
try{
|
||||
DiscordRPC.INSTANCE.Discord_Initialize(discordID, null, true, "1127400");
|
||||
DiscordRPC.connect(discordID);
|
||||
Log.info("Initialized Discord rich presence.");
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(DiscordRPC.INSTANCE::Discord_Shutdown));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(DiscordRPC::close));
|
||||
}catch(NoDiscordClientException none){
|
||||
//don't log if no client is found
|
||||
useDiscord = false;
|
||||
}catch(Throwable t){
|
||||
useDiscord = false;
|
||||
Log.err("Failed to initialize discord. Enable debug logging for details.");
|
||||
Log.debug("Discord init error: \n@\n", Strings.getStackTrace(t));
|
||||
Log.warn("Failed to initialize Discord RPC - you are likely using a JVM <16.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +130,40 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
SVars.user = new SUser();
|
||||
boolean[] isShutdown = {false};
|
||||
|
||||
service = new GameService(){
|
||||
|
||||
@Override
|
||||
public boolean enabled(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeAchievement(String name){
|
||||
SVars.stats.stats.setAchievement(name);
|
||||
SVars.stats.stats.storeStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAchieved(String name){
|
||||
return SVars.stats.stats.isAchieved(name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStat(String name, int def){
|
||||
return SVars.stats.stats.getStatI(name, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStat(String name, int amount){
|
||||
SVars.stats.stats.setStatI(name, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeStats(){
|
||||
SVars.stats.onUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
Events.on(ClientLoadEvent.class, event -> {
|
||||
Core.settings.defaults("name", SVars.net.friends.getPersonaName());
|
||||
if(player.name.isEmpty()){
|
||||
@@ -246,7 +288,6 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
String uiState = "";
|
||||
|
||||
if(inGame){
|
||||
//TODO implement nice name for sector
|
||||
gameMapWithWave = Strings.capitalize(Strings.stripColors(state.map.name()));
|
||||
|
||||
if(state.rules.waves){
|
||||
@@ -267,7 +308,7 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
}
|
||||
|
||||
if(useDiscord){
|
||||
DiscordRichPresence presence = new DiscordRichPresence();
|
||||
RichPresence presence = new RichPresence();
|
||||
|
||||
if(inGame){
|
||||
presence.state = gameMode + gamePlayersSuffix;
|
||||
@@ -281,7 +322,7 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
|
||||
presence.largeImageKey = "logo";
|
||||
|
||||
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence);
|
||||
DiscordRPC.send(presence);
|
||||
}
|
||||
|
||||
if(steam){
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
package mindustry.desktop.steam;
|
||||
|
||||
public enum SAchievement{
|
||||
kill1kEnemies(SStat.unitsDestroyed, 1000),
|
||||
kill100kEnemies(SStat.unitsDestroyed, 100_000),
|
||||
launch100kItems(SStat.itemsLaunched, 100_000),
|
||||
|
||||
produce5kMin(SStat.maxProduction, 5000),
|
||||
produce50kMin(SStat.maxProduction, 50_000),
|
||||
win10Attack(SStat.attacksWon, 10),
|
||||
win10PvP(SStat.pvpsWon, 10),
|
||||
defeatAttack5Waves,
|
||||
launch30Times(SStat.timesLaunched, 30),
|
||||
captureBackground,
|
||||
survive100Waves(SStat.maxWavesSurvived, 100),
|
||||
researchAll,
|
||||
shockWetEnemy,
|
||||
killEnemyPhaseWall,
|
||||
researchRouter,
|
||||
place10kBlocks(SStat.blocksBuilt, 10_000),
|
||||
destroy1kBlocks(SStat.blocksDestroyed, 1000),
|
||||
overheatReactor(SStat.reactorsOverheated, 1),
|
||||
make10maps(SStat.mapsMade, 10),
|
||||
downloadMapWorkshop,
|
||||
publishMap(SStat.mapsPublished, 1),
|
||||
defeatBoss(SStat.bossesDefeated, 1),
|
||||
captureAllSectors,
|
||||
control10Sectors(SStat.sectorsControlled, 10),
|
||||
drop10kitems,
|
||||
powerupImpactReactor,
|
||||
obtainThorium,
|
||||
obtainTitanium,
|
||||
suicideBomb,
|
||||
buildGroundFactory,
|
||||
issueAttackCommand,
|
||||
active100Units(SStat.maxUnitActive, 100),
|
||||
build1000Units(SStat.unitsBuilt, 1000),
|
||||
buildAllUnits(SStat.unitTypesBuilt, 30),
|
||||
buildT5,
|
||||
pickupT5,
|
||||
active10Polys,
|
||||
dieExclusion,
|
||||
drown,
|
||||
fillCoreAllCampaign,
|
||||
hostServer10(SStat.maxPlayersServer, 10),
|
||||
buildMeltdownSpectre, //technically inaccurate
|
||||
launchItemPad,
|
||||
chainRouters,
|
||||
circleConveyor,
|
||||
becomeRouter,
|
||||
create20Schematics(SStat.schematicsCreated, 20),
|
||||
survive10WavesNoBlocks,
|
||||
captureNoBlocksBroken,
|
||||
useFlameAmmo,
|
||||
coolTurret,
|
||||
enablePixelation,
|
||||
openWiki,
|
||||
useAccelerator,
|
||||
unlockAllZones,
|
||||
|
||||
;
|
||||
|
||||
private final SStat stat;
|
||||
private final int statGoal;
|
||||
public static final SAchievement[] all = values();
|
||||
|
||||
/** Creates an achievement that is triggered when this stat reaches a number.*/
|
||||
SAchievement(SStat stat, int goal){
|
||||
this.stat = stat;
|
||||
this.statGoal = goal;
|
||||
}
|
||||
|
||||
SAchievement(){
|
||||
this(null, 0);
|
||||
}
|
||||
|
||||
public void complete(){
|
||||
if(!isAchieved()){
|
||||
SVars.stats.stats.setAchievement(name());
|
||||
SVars.stats.stats.storeStats();
|
||||
}
|
||||
}
|
||||
|
||||
public void checkCompletion(){
|
||||
if(!isAchieved() && stat != null && stat.get() >= statGoal){
|
||||
complete();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAchieved(){
|
||||
return SVars.stats.stats.isAchieved(name(), false);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,7 @@ import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import com.codedisaster.steamworks.*;
|
||||
import com.codedisaster.steamworks.SteamFriends.*;
|
||||
import com.codedisaster.steamworks.SteamMatchmaking.*;
|
||||
import com.codedisaster.steamworks.SteamNetworking.*;
|
||||
import mindustry.core.*;
|
||||
@@ -58,6 +56,11 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
int fromID = from.getAccountID();
|
||||
Object output = serializer.read(readBuffer);
|
||||
|
||||
//it may be theoretically possible for this to be a framework message, if the packet is malicious or corrupted
|
||||
if(!(output instanceof Packet)) return;
|
||||
|
||||
Packet pack = (Packet)output;
|
||||
|
||||
if(net.server()){
|
||||
SteamConnection con = steamConnections.get(fromID);
|
||||
try{
|
||||
@@ -74,13 +77,13 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
net.handleServerReceived(con, c);
|
||||
}
|
||||
|
||||
net.handleServerReceived(con, output);
|
||||
net.handleServerReceived(con, pack);
|
||||
}catch(Throwable e){
|
||||
Log.err(e);
|
||||
}
|
||||
}else if(currentServer != null && fromID == currentServer.getAccountID()){
|
||||
try{
|
||||
net.handleClientReceived(output);
|
||||
net.handleClientReceived(pack);
|
||||
}catch(Throwable t){
|
||||
net.handleException(t);
|
||||
}
|
||||
@@ -120,7 +123,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendClient(Object object, SendMode mode){
|
||||
public void sendClient(Object object, boolean reliable){
|
||||
if(isSteamClient()){
|
||||
if(currentServer == null){
|
||||
Log.info("Not connected, quitting.");
|
||||
@@ -134,17 +137,15 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
int length = writeBuffer.position();
|
||||
writeBuffer.flip();
|
||||
|
||||
snet.sendP2PPacket(currentServer, writeBuffer, mode == SendMode.tcp || length >= 1200 ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
snet.sendP2PPacket(currentServer, writeBuffer, reliable || length >= 1200 ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
}catch(Exception e){
|
||||
net.showError(e);
|
||||
}
|
||||
Pools.free(object);
|
||||
}else{
|
||||
provider.sendClient(object, mode);
|
||||
provider.sendClient(object, reliable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void disconnectClient(){
|
||||
if(isSteamClient()){
|
||||
@@ -163,6 +164,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
@Override
|
||||
public void discoverServers(Cons<Host> callback, Runnable done){
|
||||
smat.addRequestLobbyListResultCountFilter(32);
|
||||
smat.addRequestLobbyListDistanceFilter(LobbyDistanceFilter.Worldwide);
|
||||
smat.requestLobbyList();
|
||||
lobbyCallback = callback;
|
||||
|
||||
@@ -226,11 +228,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoritesListChanged(int i, int i1, int i2, int i3, int i4, boolean b, int i5){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyInvite(SteamID steamIDUser, SteamID steamIDLobby, long gameID){
|
||||
Log.info("onLobbyInvite @ @ @", steamIDLobby.getAccountID(), steamIDUser.getAccountID(), gameID);
|
||||
@@ -279,11 +276,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
Core.app.post(() -> Core.app.post(() -> Core.app.post(() -> Log.info("Server: @\nClient: @\nActive: @", net.server(), net.client(), net.active()))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyDataUpdate(SteamID steamID, SteamID steamID1, boolean b){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyChatUpdate(SteamID lobby, SteamID who, SteamID changer, ChatMemberStateChange change){
|
||||
Log.info("lobby @: @ caused @'s change: @", lobby.getAccountID(), who.getAccountID(), changer.getAccountID(), change);
|
||||
@@ -301,16 +293,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyChatMessage(SteamID steamID, SteamID steamID1, ChatEntryType chatEntryType, int i){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyGameCreated(SteamID steamID, SteamID steamID1, int i, short i1){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyMatchList(int matches){
|
||||
Log.info("found @ matches @", matches, lobbyDoneCallback);
|
||||
@@ -331,7 +313,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
smat.getNumLobbyMembers(lobby),
|
||||
Strings.parseInt(smat.getLobbyData(lobby, "version"), -1),
|
||||
smat.getLobbyData(lobby, "versionType"),
|
||||
mode == null || mode.isEmpty() ? Gamemode.survival : Gamemode.valueOf(mode),
|
||||
Gamemode.valueOf(mode),
|
||||
smat.getLobbyMemberLimit(lobby),
|
||||
"",
|
||||
null
|
||||
@@ -349,11 +331,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyKicked(SteamID steamID, SteamID steamID1, boolean b){
|
||||
Log.info("Kicked: @ @ @", steamID, steamID1, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLobbyCreated(SteamResult result, SteamID steamID){
|
||||
if(!net.server()){
|
||||
@@ -381,11 +358,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoritesListAccountsUpdated(SteamResult steamResult){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onP2PSessionConnectFail(SteamID steamIDRemote, P2PSessionError sessionError){
|
||||
if(net.server()){
|
||||
@@ -406,50 +378,14 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetPersonaNameResponse(boolean b, boolean b1, SteamResult steamResult){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPersonaStateChange(SteamID steamID, PersonaChange personaChange){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameOverlayActivated(boolean b){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameLobbyJoinRequested(SteamID lobby, SteamID steamIDFriend){
|
||||
Log.info("onGameLobbyJoinRequested @ @", lobby, steamIDFriend);
|
||||
smat.joinLobby(lobby);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAvatarImageLoaded(SteamID steamID, int i, int i1, int i2){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFriendRichPresenceUpdate(SteamID steamID, int i){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameRichPresenceJoinRequested(SteamID steamID, String connect){
|
||||
Log.info("onGameRichPresenceJoinRequested @ @", steamID, connect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameServerChangeRequested(String server, String password){
|
||||
|
||||
}
|
||||
|
||||
public class SteamConnection extends NetConnection{
|
||||
final SteamID sid;
|
||||
final P2PSessionState state = new P2PSessionState();
|
||||
|
||||
public SteamConnection(SteamID sid){
|
||||
super(sid.getAccountID() + "");
|
||||
@@ -458,7 +394,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object object, SendMode mode){
|
||||
public void send(Object object, boolean reliable){
|
||||
try{
|
||||
writeBuffer.limit(writeBuffer.capacity());
|
||||
writeBuffer.position(0);
|
||||
@@ -466,7 +402,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
int length = writeBuffer.position();
|
||||
writeBuffer.flip();
|
||||
|
||||
snet.sendP2PPacket(sid, writeBuffer, mode == SendMode.tcp || length >= 1200 ? object instanceof StreamChunk ? P2PSend.ReliableWithBuffering : P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
snet.sendP2PPacket(sid, writeBuffer, reliable || length >= 1200 ? object instanceof StreamChunk ? P2PSend.ReliableWithBuffering : P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
}catch(Exception e){
|
||||
Log.err(e);
|
||||
Log.info("Error sending packet. Disconnecting invalid client!");
|
||||
@@ -479,7 +415,8 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
|
||||
@Override
|
||||
public boolean isConnected(){
|
||||
snet.getP2PSessionState(sid, state);
|
||||
//TODO ???
|
||||
//snet.getP2PSessionState(sid, state);
|
||||
return true;//state.isConnectionActive();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package mindustry.desktop.steam;
|
||||
|
||||
public enum SStat{
|
||||
unitsDestroyed,
|
||||
attacksWon,
|
||||
pvpsWon,
|
||||
timesLaunched,
|
||||
blocksDestroyed,
|
||||
itemsLaunched,
|
||||
reactorsOverheated,
|
||||
maxUnitActive,
|
||||
unitTypesBuilt,
|
||||
unitsBuilt,
|
||||
bossesDefeated,
|
||||
maxPlayersServer,
|
||||
mapsMade,
|
||||
mapsPublished,
|
||||
maxWavesSurvived,
|
||||
blocksBuilt,
|
||||
maxProduction,
|
||||
sectorsControlled,
|
||||
schematicsCreated,
|
||||
;
|
||||
|
||||
public int get(){
|
||||
return SVars.stats.stats.getStatI(name(), 0);
|
||||
}
|
||||
|
||||
public void max(int amount){
|
||||
if(amount > get()){
|
||||
set(amount);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(int amount){
|
||||
SVars.stats.stats.setStatI(name(), amount);
|
||||
SVars.stats.onUpdate();
|
||||
|
||||
for(SAchievement a : SAchievement.all){
|
||||
a.checkCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int amount){
|
||||
set(get() + amount);
|
||||
}
|
||||
|
||||
public void add(){
|
||||
add(1);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,27 @@
|
||||
package mindustry.desktop.steam;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import com.codedisaster.steamworks.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.game.SectorInfo.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.distribution.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.desktop.steam.SAchievement.*;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SStats implements SteamUserStatsCallback{
|
||||
public final SteamUserStats stats = new SteamUserStats(this);
|
||||
|
||||
private boolean updated = false;
|
||||
private int statSavePeriod = 4; //in minutes
|
||||
|
||||
private ObjectSet<String> blocksBuilt = new ObjectSet<>(), unitsBuilt = new ObjectSet<>();
|
||||
private ObjectSet<UnitType> t5s = new ObjectSet<>();
|
||||
private IntSet checked = new IntSet();
|
||||
|
||||
public SStats(){
|
||||
stats.requestCurrentStats();
|
||||
|
||||
Events.on(ClientLoadEvent.class, e -> {
|
||||
unitsBuilt = Core.settings.getJson("units-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
blocksBuilt = Core.settings.getJson("blocks-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
t5s = ObjectSet.with(UnitTypes.omura, UnitTypes.reign, UnitTypes.toxopid, UnitTypes.eclipse, UnitTypes.oct, UnitTypes.corvus);
|
||||
|
||||
Core.app.addListener(new ApplicationListener(){
|
||||
Interval i = new Interval();
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(i.get(60f)){
|
||||
checkUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Timer.schedule(() -> {
|
||||
if(updated){
|
||||
stats.storeStats();
|
||||
}
|
||||
}, statSavePeriod * 60, statSavePeriod * 60);
|
||||
|
||||
if(Items.thorium.unlocked()) obtainThorium.complete();
|
||||
if(Items.titanium.unlocked()) obtainTitanium.complete();
|
||||
if(!content.sectors().contains(s -> s.locked())){
|
||||
unlockAllZones.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -65,287 +29,9 @@ public class SStats implements SteamUserStatsCallback{
|
||||
this.updated = true;
|
||||
}
|
||||
|
||||
void checkUpdate(){
|
||||
if(campaign()){
|
||||
SStat.maxUnitActive.max(Groups.unit.count(t -> t.team == player.team()));
|
||||
|
||||
if(Groups.unit.count(u -> u.type == UnitTypes.poly && u.team == player.team()) >= 10){
|
||||
active10Polys.complete();
|
||||
}
|
||||
|
||||
for(Building entity : player.team().cores()){
|
||||
if(!content.items().contains(i -> entity.items.get(i) < entity.block.itemCapacity)){
|
||||
fillCoreAllCampaign.complete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerEvents(){
|
||||
|
||||
Events.on(UnitDestroyEvent.class, e -> {
|
||||
if(campaign()){
|
||||
if(e.unit.team != Vars.player.team()){
|
||||
SStat.unitsDestroyed.add();
|
||||
|
||||
if(e.unit.isBoss()){
|
||||
SStat.bossesDefeated.add();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(TurnEvent.class, e -> {
|
||||
float total = 0;
|
||||
for(Planet planet : content.planets()){
|
||||
for(Sector sec : planet.sectors){
|
||||
if(sec.hasBase()){
|
||||
for(ExportStat v : sec.info.production.values()){
|
||||
if(v.mean > 0) total += v.mean * 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SStat.maxProduction.max(Math.round(total));
|
||||
});
|
||||
|
||||
Events.run(Trigger.newGame, () -> Core.app.post(() -> {
|
||||
if(campaign() && player.core() != null && player.core().items.total() >= 10 * 1000){
|
||||
drop10kitems.complete();
|
||||
}
|
||||
}));
|
||||
|
||||
Events.on(CommandIssueEvent.class, e -> {
|
||||
if(campaign() && e.command == UnitCommand.attack){
|
||||
issueAttackCommand.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockBuildEndEvent.class, e -> {
|
||||
if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){
|
||||
SStat.blocksBuilt.add();
|
||||
|
||||
if(e.tile.block() == Blocks.router && e.tile.build.proximity().contains(t -> t.block == Blocks.router)){
|
||||
chainRouters.complete();
|
||||
}
|
||||
|
||||
if(e.tile.block() == Blocks.groundFactory){
|
||||
buildGroundFactory.complete();
|
||||
}
|
||||
|
||||
if(blocksBuilt.add(e.tile.block().name)){
|
||||
if(blocksBuilt.contains("meltdown") && blocksBuilt.contains("spectre") && blocksBuilt.contains("foreshadow")){
|
||||
buildMeltdownSpectre.complete();
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
if(e.tile.block() instanceof Conveyor){
|
||||
checked.clear();
|
||||
check: {
|
||||
Tile current = e.tile;
|
||||
for(int i = 0; i < 4; i++){
|
||||
checked.add(current.pos());
|
||||
if(current.build == null) break check;
|
||||
Tile next = current.nearby(current.build.rotation);
|
||||
if(next != null && next.block() instanceof Conveyor){
|
||||
current = next;
|
||||
}else{
|
||||
break check;
|
||||
}
|
||||
}
|
||||
|
||||
if(current == e.tile && checked.size == 4){
|
||||
circleConveyor.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitCreateEvent.class, e -> {
|
||||
if(campaign()){
|
||||
if(unitsBuilt.add(e.unit.type.name)){
|
||||
SStat.unitTypesBuilt.set(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden()));
|
||||
}
|
||||
|
||||
if(t5s.contains(e.unit.type)){
|
||||
buildT5.complete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitControlEvent.class, e -> {
|
||||
if(e.unit instanceof BlockUnitc && ((BlockUnitc)e.unit).tile().block == Blocks.router){
|
||||
becomeRouter.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SchematicCreateEvent.class, e -> {
|
||||
SStat.schematicsCreated.add();
|
||||
});
|
||||
|
||||
Events.on(BlockDestroyEvent.class, e -> {
|
||||
if(campaign() && e.tile.team() != player.team()){
|
||||
SStat.blocksDestroyed.add();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(MapMakeEvent.class, e -> SStat.mapsMade.add());
|
||||
|
||||
Events.on(MapPublishEvent.class, e -> SStat.mapsPublished.add());
|
||||
|
||||
Events.on(UnlockEvent.class, e -> {
|
||||
if(e.content == Items.thorium) obtainThorium.complete();
|
||||
if(e.content == Items.titanium) obtainTitanium.complete();
|
||||
if(e.content instanceof SectorPreset && !content.sectors().contains(s -> s.locked())){
|
||||
unlockAllZones.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.run(Trigger.openWiki, openWiki::complete);
|
||||
|
||||
Events.run(Trigger.exclusionDeath, dieExclusion::complete);
|
||||
|
||||
Events.on(UnitDrownEvent.class, e -> {
|
||||
if(campaign() && e.unit.isPlayer()){
|
||||
drown.complete();
|
||||
}
|
||||
});
|
||||
|
||||
trigger(Trigger.acceleratorUse, useAccelerator);
|
||||
|
||||
trigger(Trigger.impactPower, powerupImpactReactor);
|
||||
|
||||
trigger(Trigger.flameAmmo, useFlameAmmo);
|
||||
|
||||
trigger(Trigger.turretCool, coolTurret);
|
||||
|
||||
trigger(Trigger.suicideBomb, suicideBomb);
|
||||
|
||||
Events.run(Trigger.enablePixelation, enablePixelation::complete);
|
||||
|
||||
Events.run(Trigger.thoriumReactorOverheat, () -> {
|
||||
if(campaign()){
|
||||
SStat.reactorsOverheated.add();
|
||||
}
|
||||
});
|
||||
|
||||
trigger(Trigger.shock, shockWetEnemy);
|
||||
|
||||
trigger(Trigger.phaseDeflectHit, killEnemyPhaseWall);
|
||||
|
||||
Events.on(LaunchItemEvent.class, e -> {
|
||||
if(campaign()){
|
||||
launchItemPad.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(PickupEvent.class, e -> {
|
||||
if(e.carrier.isPlayer() && campaign() && e.unit != null && t5s.contains(e.unit.type)){
|
||||
pickupT5.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitCreateEvent.class, e -> {
|
||||
if(campaign() && e.unit.team() == player.team()){
|
||||
SStat.unitsBuilt.add();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SectorLaunchEvent.class, e -> {
|
||||
SStat.timesLaunched.add();
|
||||
});
|
||||
|
||||
Events.on(LaunchItemEvent.class, e -> {
|
||||
SStat.itemsLaunched.add(e.stack.amount);
|
||||
});
|
||||
|
||||
Events.on(WaveEvent.class, e -> {
|
||||
if(campaign()){
|
||||
SStat.maxWavesSurvived.max(Vars.state.wave);
|
||||
|
||||
if(state.stats.buildingsBuilt == 0 && state.wave >= 10){
|
||||
survive10WavesNoBlocks.complete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(PlayerJoin.class, e -> {
|
||||
if(Vars.net.server()){
|
||||
SStat.maxPlayersServer.max(Groups.player.size());
|
||||
}
|
||||
});
|
||||
|
||||
Runnable checkUnlocks = () -> {
|
||||
if(Blocks.router.unlocked()) researchRouter.complete();
|
||||
|
||||
if(!TechTree.all.contains(t -> t.content.locked())){
|
||||
researchAll.complete();
|
||||
}
|
||||
};
|
||||
|
||||
//check unlocked stuff on load as well
|
||||
Events.on(ResearchEvent.class, e -> checkUnlocks.run());
|
||||
Events.on(UnlockEvent.class, e -> checkUnlocks.run());
|
||||
Events.on(ClientLoadEvent.class, e -> checkUnlocks.run());
|
||||
|
||||
Events.on(WinEvent.class, e -> {
|
||||
if(state.rules.pvp){
|
||||
SStat.pvpsWon.add();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SectorCaptureEvent.class, e -> {
|
||||
if(e.sector.isBeingPlayed() || net.client()){
|
||||
if(Vars.state.wave <= 5 && state.rules.attackMode){
|
||||
defeatAttack5Waves.complete();
|
||||
}
|
||||
|
||||
if(state.stats.buildingsDestroyed == 0){
|
||||
captureNoBlocksBroken.complete();
|
||||
}
|
||||
}
|
||||
|
||||
if(Vars.state.rules.attackMode){
|
||||
SStat.attacksWon.add();
|
||||
}
|
||||
|
||||
if(!e.sector.isBeingPlayed() && !net.client()){
|
||||
captureBackground.complete();
|
||||
}
|
||||
|
||||
if(!e.sector.planet.sectors.contains(s -> !s.hasBase())){
|
||||
captureAllSectors.complete();
|
||||
}
|
||||
|
||||
SStat.sectorsControlled.set(e.sector.planet.sectors.count(Sector::hasBase));
|
||||
});
|
||||
}
|
||||
|
||||
private void save(){
|
||||
Core.settings.putJson("units-built" , String.class, unitsBuilt);
|
||||
Core.settings.putJson("blocks-built" , String.class, blocksBuilt);
|
||||
}
|
||||
|
||||
private void trigger(Trigger trigger, SAchievement ach){
|
||||
Events.run(trigger, () -> {
|
||||
if(campaign()){
|
||||
ach.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean campaign(){
|
||||
return Vars.state.isCampaign();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserStatsReceived(long gameID, SteamID steamID, SteamResult result){
|
||||
registerEvents();
|
||||
service.init();
|
||||
|
||||
if(result != SteamResult.OK){
|
||||
Log.err("Failed to receive steam stats: @", result);
|
||||
@@ -362,34 +48,4 @@ public class SStats implements SteamUserStatsCallback{
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserStatsUnloaded(SteamID steamID){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserAchievementStored(long l, boolean b, String s, int i, int i1){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeaderboardFindResult(SteamLeaderboardHandle steamLeaderboardHandle, boolean b){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeaderboardScoresDownloaded(SteamLeaderboardHandle steamLeaderboardHandle, SteamLeaderboardEntriesHandle steamLeaderboardEntriesHandle, int i){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeaderboardScoreUploaded(boolean b, SteamLeaderboardHandle steamLeaderboardHandle, int i, boolean b1, int i1, int i2){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGlobalStatsReceived(long l, SteamResult steamResult){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
package mindustry.desktop.steam;
|
||||
|
||||
import com.codedisaster.steamworks.*;
|
||||
import com.codedisaster.steamworks.SteamAuth.*;
|
||||
|
||||
public class SUser implements SteamUserCallback{
|
||||
public final SteamUser user = new SteamUser(this);
|
||||
|
||||
@Override
|
||||
public void onValidateAuthTicket(SteamID steamID, AuthSessionResponse authSessionResponse, SteamID ownerSteamID){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMicroTxnAuthorization(int appID, long orderID, boolean authorized){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptedAppTicket(SteamResult result){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package mindustry.desktop.steam;
|
||||
|
||||
import arc.*;
|
||||
import com.codedisaster.steamworks.*;
|
||||
import com.codedisaster.steamworks.SteamRemoteStorage.*;
|
||||
import com.codedisaster.steamworks.SteamUGC.*;
|
||||
import arc.struct.*;
|
||||
import arc.files.*;
|
||||
import arc.func.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import com.codedisaster.steamworks.*;
|
||||
import com.codedisaster.steamworks.SteamRemoteStorage.*;
|
||||
import com.codedisaster.steamworks.SteamUGC.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.maps.*;
|
||||
import mindustry.mod.Mods.*;
|
||||
import mindustry.service.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.dialogs.*;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class SWorkshop implements SteamUGCCallback{
|
||||
workshopFiles.put(LoadedMod.class, folders.select(f -> f.child("mod.json").exists() || f.child("mod.hjson").exists()));
|
||||
|
||||
if(!workshopFiles.get(Map.class).isEmpty()){
|
||||
SAchievement.downloadMapWorkshop.complete();
|
||||
Achievement.downloadMapWorkshop.complete();
|
||||
}
|
||||
|
||||
workshopFiles.each((type, list) -> {
|
||||
@@ -171,7 +172,7 @@ public class SWorkshop implements SteamUGCCallback{
|
||||
ugc.submitItemUpdate(h, changelog == null ? "<Created>" : changelog);
|
||||
|
||||
if(p instanceof Map){
|
||||
SAchievement.publishMap.complete();
|
||||
Achievement.publishMap.complete();
|
||||
}
|
||||
}, () -> p.addSteamID(sid));
|
||||
}
|
||||
@@ -228,11 +229,6 @@ public class SWorkshop implements SteamUGCCallback{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestUGCDetails(SteamUGCDetails details, SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUGCQueryCompleted(SteamUGCQuery query, int numResultsReturned, int totalMatchingResults, boolean isCachedData, SteamResult result){
|
||||
Log.info("GET QUERY " + query);
|
||||
@@ -263,7 +259,7 @@ public class SWorkshop implements SteamUGCCallback{
|
||||
ItemInstallInfo info = new ItemInstallInfo();
|
||||
ugc.getItemInstallInfo(publishedFileID, info);
|
||||
Log.info("Item subscribed from @", info.getFolder());
|
||||
SAchievement.downloadMapWorkshop.complete();
|
||||
Achievement.downloadMapWorkshop.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -311,42 +307,12 @@ public class SWorkshop implements SteamUGCCallback{
|
||||
|
||||
@Override
|
||||
public void onDownloadItemResult(int appID, SteamPublishedFileID publishedFileID, SteamResult result){
|
||||
SAchievement.downloadMapWorkshop.complete();
|
||||
Achievement.downloadMapWorkshop.complete();
|
||||
ItemInstallInfo info = new ItemInstallInfo();
|
||||
ugc.getItemInstallInfo(publishedFileID, info);
|
||||
Log.info("Item downloaded to @", info.getFolder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserFavoriteItemsListChanged(SteamPublishedFileID publishedFileID, boolean wasAddRequest, SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetUserItemVote(SteamPublishedFileID publishedFileID, boolean voteUp, SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetUserItemVote(SteamPublishedFileID publishedFileID, boolean votedUp, boolean votedDown, boolean voteSkipped, SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartPlaytimeTracking(SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopPlaytimeTracking(SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopPlaytimeTrackingForAllItems(SteamResult result){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteItem(SteamPublishedFileID publishedFileID, SteamResult result){
|
||||
ItemInstallInfo info = new ItemInstallInfo();
|
||||
|
||||
Reference in New Issue
Block a user