Skip to content

Commit

Permalink
feat: 投票可能時刻の表示機能を追加
Browse files Browse the repository at this point in the history
  • Loading branch information
Toshimichi0915 committed Oct 12, 2023
1 parent af527ca commit 82c23b1
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/main/java/net/toshimichi/kzeplus/KzePlus.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import net.toshimichi.kzeplus.modules.PlayInfoModule;
import net.toshimichi.kzeplus.modules.TimerInfoModule;
import net.toshimichi.kzeplus.modules.VisibiiltyToggleModule;
import net.toshimichi.kzeplus.modules.VoteInfoModule;
import net.toshimichi.kzeplus.modules.WeaponContextModule;
import net.toshimichi.kzeplus.modules.WeaponInfoModule;
import net.toshimichi.kzeplus.modules.WidgetContextModule;
Expand Down Expand Up @@ -96,6 +97,7 @@ public void onInitialize() {
registerModule(new TimerInfoModule());
registerModule(new KillLogModule());
registerModule(new VisibiiltyToggleModule());
registerModule(new VoteInfoModule());
registerModule(new WeaponContextModule());
registerModule(new WeaponInfoModule());
registerModule(new WidgetContextModule());
Expand Down
156 changes: 156 additions & 0 deletions src/main/java/net/toshimichi/kzeplus/modules/VoteInfoModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package net.toshimichi.kzeplus.modules;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.Data;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.util.math.MatrixStack;
import net.toshimichi.kzeplus.KzePlus;
import net.toshimichi.kzeplus.context.widget.Widget;
import net.toshimichi.kzeplus.events.ClientTickEvent;
import net.toshimichi.kzeplus.events.EventTarget;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Map;

public class VoteInfoModule implements Module {

private static final Gson GSON = new Gson();
private static final TypeToken<List<VoteData>> TYPE_TOKEN = new TypeToken<>() {};
private static final int PING_INTERVAL = 30000;

private int nextVoteTicks;
private boolean successful;
private Thread thread;

public void heartbeat() {
try {
while (!Thread.currentThread().isInterrupted()) {
try {
ping();
successful = true;
} catch (IOException e) {
successful = false;
e.printStackTrace();
} finally {
Thread.sleep(PING_INTERVAL);
}
}
} catch (InterruptedException e) {
// module has been disabled
}
}

public void ping() throws IOException {
String username = MinecraftClient.getInstance().getSession().getUsername();
URLConnection co = new URL("https://kze.toshimichi.net/votes?username=" + username).openConnection();

String content;
try (InputStream in = co.getInputStream()) {
content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}

List<VoteData> voteData = GSON.fromJson(content, TYPE_TOKEN.getType());
nextVoteTicks = (int) voteData
.stream()
.map(it -> Instant.parse(it.getCreatedAt()))
.map(it -> Duration.between(Instant.now(), it.plus(Duration.ofDays(1))))
.mapToLong(Duration::getSeconds)
.map(it -> it * 20)
.filter(it -> it > 0)
.max()
.orElse(0);
}

@Override
public void onEnable() {
KzePlus.getInstance().getEventRegistry().register(this);
thread = new Thread(this::heartbeat);
thread.setDaemon(true);
thread.start();
}

@Override
public void onDisable() {
KzePlus.getInstance().getEventRegistry().unregister(this);
thread.interrupt();
}

@EventTarget
public void reduceNextVoteTicks(ClientTickEvent e) {
nextVoteTicks--;
}

@Override
public Map<String, Widget> getWidgets() {
return Map.of("vote_info", new VoteInfoWidget());
}

@Data
private static class VoteData {
String username;
String createdAt;
}

private class VoteInfoWidget implements Widget {

private boolean valid;
private boolean canVote;
private String message;

@Override
public void update(boolean placeholder) {
this.valid = successful && KzePlus.getInstance().getOptions().isShowVote() || placeholder;
if (placeholder) {
canVote = true;
message = "投票できます";
} else if (nextVoteTicks > 0) {
canVote = false;
int hours = nextVoteTicks / 20 / (60 * 60);
int minutes = nextVoteTicks / 20 / 60 % 60;
int seconds = nextVoteTicks / 20 % 60;
message = String.format("投票可能まで: %02d:%02d:%02d", hours, minutes, seconds);
} else {
canVote = true;
message = "投票できます";
}
}

@Override
public void render(int x, int y, MatrixStack stack, float tickDelta) {
TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
InGameHud.fill(stack, x, y, x + getWidth(), y + getHeight(), 0x80000000);
InGameHud.drawTextWithShadow(stack, textRenderer, message, x + 5, y + 5, canVote ? 0x54fb54 : 0xffffff);
}

@Override
public int getWidth() {
return 125;
}

@Override
public int getHeight() {
return 20;
}

@Override
public boolean isVisible() {
return valid;
}

@Override
public List<GameOptions> getOptions() {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import net.toshimichi.kzeplus.events.EventTarget;
import net.toshimichi.kzeplus.events.InGameHudRenderEvent;

import java.util.ArrayDeque;

public class WidgetContextModule implements Module {

private boolean flushed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ public class KzeOptions {
private boolean showPlayTime = true;
private boolean showTeam = true;
private boolean showBonus = true;
private boolean showVote = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protected void init() {
SimpleOption.ofBoolean("kze_plus.options.show_play_time", options.isShowPlayTime(), options::setShowPlayTime),
SimpleOption.ofBoolean("kze_plus.options.show_team", options.isShowTeam(), options::setShowTeam),
SimpleOption.ofBoolean("kze_plus.options.show_bonus", options.isShowBonus(), options::setShowBonus),
SimpleOption.ofBoolean("kze_plus.options.show_vote", options.isShowVote(), options::setShowVote),
};

list = new OptionListWidget(client, width, height, 32, height - 32, 25);
Expand Down
30 changes: 20 additions & 10 deletions src/main/resources/assets/kze_plus/default_layout.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,30 @@
"y": 20,
"children": [
{
"id": "weapon_info",
"id": "vote_info",
"anchor": "BOTTOM_LEFT",
"origin": "TOP_LEFT",
"x": 0,
"y": 10,
"children": []
},
{
"id": "timer_info",
"anchor": "BOTTOM_LEFT",
"origin": "TOP_LEFT",
"x": 0,
"y": 50,
"children": []
"children": [
{
"id": "weapon_info",
"anchor": "BOTTOM_LEFT",
"origin": "TOP_LEFT",
"x": 0,
"y": 10,
"children": [
{
"id": "timer_info",
"anchor": "BOTTOM_LEFT",
"origin": "TOP_LEFT",
"x": 0,
"y": 10,
"children": []
}
]
}
]
},
{
"id": "kill_log",
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/assets/kze_plus/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
"kze_plus.options.show_exp": "経験値を表示する",
"kze_plus.options.show_play_time": "プレイ時間を表示する",
"kze_plus.options.show_team": "チームを表示する",
"kze_plus.options.show_bonus": "防衛・被弾ボーナスを表示する"
"kze_plus.options.show_bonus": "防衛・被弾ボーナスを表示する",
"kze_plus.options.show_vote": "投票を表示する"
}

0 comments on commit 82c23b1

Please sign in to comment.