Commit 0bfa1fa0 authored by Akka's avatar Akka Committed by GitHub
Browse files

Merge pull request #8 from Grasscutters/development

Development
parents 65861c3c 056b5b80
...@@ -11,21 +11,27 @@ import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason; ...@@ -11,21 +11,27 @@ import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
import java.util.List; import java.util.List;
public class PacketEntityFightPropChangeReasonNotify extends BasePacket { public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, List<Integer> param, PropChangeReason reason, ChangeHpReason changeHpReason) { public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, List<Integer> param, PropChangeReason reason, ChangeHpReason changeHpReason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify); super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify.Builder proto = EntityFightPropChangeReasonNotify.newBuilder() EntityFightPropChangeReasonNotify.Builder proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId()) .setEntityId(entity.getId())
.setPropType(prop.getId()) .setPropType(prop.getId())
.setPropDelta(value) .setPropDelta(value)
.setReason(reason) .setReason(reason)
.setChangeHpReason(changeHpReason); .setChangeHpReason(changeHpReason);
for(int p: param){
for(int p : param){
proto.addParamList(p); proto.addParamList(p);
} }
this.setData(proto); this.setData(proto);
} }
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason, ChangeHpReason changeHpReason) { public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason, ChangeHpReason changeHpReason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify); super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder() EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId()) .setEntityId(entity.getId())
.setPropType(prop.getId()) .setPropType(prop.getId())
...@@ -33,6 +39,20 @@ public class PacketEntityFightPropChangeReasonNotify extends BasePacket { ...@@ -33,6 +39,20 @@ public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
.setReason(reason) .setReason(reason)
.setChangeHpReason(changeHpReason) .setChangeHpReason(changeHpReason)
.build(); .build();
this.setData(proto);
}
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId())
.setPropType(prop.getId())
.setPropDelta(value)
.setReason(reason)
.build();
this.setData(proto); this.setData(proto);
} }
} }
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.data.GameData; import emu.grasscutter.game.tower.TowerManager;
import emu.grasscutter.data.def.TowerFloorData; import emu.grasscutter.game.tower.TowerScheduleManager;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TowerAllDataRspOuterClass.TowerAllDataRsp; import emu.grasscutter.net.proto.TowerAllDataRspOuterClass.TowerAllDataRsp;
import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord; import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord;
import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord; import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord;
import emu.grasscutter.net.proto.TowerLevelRecordOuterClass;
import emu.grasscutter.utils.DateHelper;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PacketTowerAllDataRsp extends BasePacket { public class PacketTowerAllDataRsp extends BasePacket {
public PacketTowerAllDataRsp() { public PacketTowerAllDataRsp(TowerScheduleManager towerScheduleManager, TowerManager towerManager) {
super(PacketOpcodes.TowerAllDataRsp); super(PacketOpcodes.TowerAllDataRsp);
var list = GameData.getTowerFloorDataMap().values().stream() var recordList = towerManager.getRecordMap().values().stream()
.map(TowerFloorData::getFloorId) .map(rec -> TowerFloorRecord.newBuilder()
.map(id -> TowerFloorRecord.newBuilder().setFloorId(id).build()) .setFloorId(rec.getFloorId())
.collect(Collectors.toList()); .setFloorStarRewardProgress(rec.getFloorStarRewardProgress())
.putAllPassedLevelMap(rec.getPassedLevelMap())
.addAllPassedLevelRecordList(buildFromPassedLevelMap(rec.getPassedLevelMap()))
.build()
)
.toList();
var openTimeMap = towerScheduleManager.getScheduleFloors().stream()
.collect(Collectors.toMap(x -> x,
y -> DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.getScheduleStartTime()))
);
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder() TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
.setTowerScheduleId(29) .setTowerScheduleId(towerScheduleManager.getCurrentTowerScheduleData().getScheduleId())
.addAllTowerFloorRecordList(list) .addAllTowerFloorRecordList(recordList)
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true)) .setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
.setNextScheduleChangeTime(Integer.MAX_VALUE) .setScheduleStartTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.putFloorOpenTimeMap(1024, 1630486800) .getScheduleStartTime()))
.putFloorOpenTimeMap(1025, 1630486800) .setNextScheduleChangeTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.putFloorOpenTimeMap(1026, 1630486800) .getNextScheduleChangeTime()))
.putFloorOpenTimeMap(1027, 1630486800) .putAllFloorOpenTimeMap(openTimeMap)
.setScheduleStartTime(1630486800) .setIsFinishedEntranceFloor(towerManager.canEnterScheduleFloor())
.build(); .build();
this.setData(proto); this.setData(proto);
} }
private List<TowerLevelRecordOuterClass.TowerLevelRecord> buildFromPassedLevelMap(Map<Integer, Integer> map){
return map.entrySet().stream()
.map(item -> TowerLevelRecordOuterClass.TowerLevelRecord.newBuilder()
.setLevelId(item.getKey())
.addAllSatisfiedCondList(IntStream.range(1, item.getValue() + 1).boxed().toList())
.build())
.toList();
}
} }
...@@ -8,13 +8,13 @@ import emu.grasscutter.net.proto.TowerLevelRecordOuterClass.TowerLevelRecord; ...@@ -8,13 +8,13 @@ import emu.grasscutter.net.proto.TowerLevelRecordOuterClass.TowerLevelRecord;
public class PacketTowerFloorRecordChangeNotify extends BasePacket { public class PacketTowerFloorRecordChangeNotify extends BasePacket {
public PacketTowerFloorRecordChangeNotify(int floorId) { public PacketTowerFloorRecordChangeNotify(int floorId, int stars, boolean canEnterScheduleFloor) {
super(PacketOpcodes.TowerFloorRecordChangeNotify); super(PacketOpcodes.TowerFloorRecordChangeNotify);
TowerFloorRecordChangeNotify proto = TowerFloorRecordChangeNotify.newBuilder() TowerFloorRecordChangeNotify proto = TowerFloorRecordChangeNotify.newBuilder()
.addTowerFloorRecordList(TowerFloorRecord.newBuilder() .addTowerFloorRecordList(TowerFloorRecord.newBuilder()
.setFloorId(floorId) .setFloorId(floorId)
.setFloorStarRewardProgress(3) .setFloorStarRewardProgress(stars)
.addPassedLevelRecordList(TowerLevelRecord.newBuilder() .addPassedLevelRecordList(TowerLevelRecord.newBuilder()
.setLevelId(1) .setLevelId(1)
.addSatisfiedCondList(1) .addSatisfiedCondList(1)
...@@ -22,7 +22,7 @@ public class PacketTowerFloorRecordChangeNotify extends BasePacket { ...@@ -22,7 +22,7 @@ public class PacketTowerFloorRecordChangeNotify extends BasePacket {
.addSatisfiedCondList(3) .addSatisfiedCondList(3)
.build()) .build())
.build()) .build())
.setIsFinishedEntranceFloor(true) .setIsFinishedEntranceFloor(canEnterScheduleFloor)
.build(); .build();
this.setData(proto); this.setData(proto);
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TowerLevelStarCondDataOuterClass.TowerLevelStarCondData;
import emu.grasscutter.net.proto.TowerLevelStarCondNotifyOuterClass.TowerLevelStarCondNotify;
public class PacketTowerLevelStarCondNotify extends BasePacket {
public PacketTowerLevelStarCondNotify(int floorId, int levelIndex) {
super(PacketOpcodes.TowerLevelStarCondNotify);
TowerLevelStarCondNotify proto = TowerLevelStarCondNotify.newBuilder()
.setFloorId(floorId)
.setLevelIndex(levelIndex)
.addCondDataList(TowerLevelStarCondData.newBuilder()
.setCondValue(1)
.build()
)
.addCondDataList(TowerLevelStarCondData.newBuilder()
.setCondValue(2)
.build()
)
.addCondDataList(TowerLevelStarCondData.newBuilder()
.setCondValue(3)
.build()
)
.build();
this.setData(proto);
}
}
package emu.grasscutter.task; package emu.grasscutter.task;
import org.quartz.JobDataMap;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
......
...@@ -67,6 +67,40 @@ public final class TaskMap { ...@@ -67,6 +67,40 @@ public final class TaskMap {
return this; return this;
} }
public boolean pauseTask(String taskName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.pauseJob(new JobKey(taskName));
} catch (SchedulerException e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean resumeTask(String taskName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.resumeJob(new JobKey(taskName));
} catch (SchedulerException e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean cancelTask(String taskName) {
Task task = this.annotations.get(taskName);
if (task == null) return false;
try {
this.unregisterTask(this.tasks.get(taskName));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public TaskMap registerTask(String taskName, TaskHandler task) { public TaskMap registerTask(String taskName, TaskHandler task) {
Task annotation = task.getClass().getAnnotation(Task.class); Task annotation = task.getClass().getAnnotation(Task.class);
this.annotations.put(taskName, annotation); this.annotations.put(taskName, annotation);
...@@ -116,7 +150,7 @@ public final class TaskMap { ...@@ -116,7 +150,7 @@ public final class TaskMap {
classes.forEach(annotated -> { classes.forEach(annotated -> {
try { try {
Task taskData = annotated.getAnnotation(Task.class); Task taskData = annotated.getAnnotation(Task.class);
Object object = annotated.newInstance(); Object object = annotated.getDeclaredConstructor().newInstance();
if (object instanceof TaskHandler) { if (object instanceof TaskHandler) {
this.registerTask(taskData.taskName(), (TaskHandler) object); this.registerTask(taskData.taskName(), (TaskHandler) object);
if (taskData.executeImmediatelyAfterReset()) { if (taskData.executeImmediatelyAfterReset()) {
......
package emu.grasscutter.utils; package emu.grasscutter.utils;
import java.util.Date;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
public final class DateHelper { public final class DateHelper {
public static Date onlyYearMonthDay(Date now) { public static Date onlyYearMonthDay(Date now) {
...@@ -13,4 +13,8 @@ public final class DateHelper { ...@@ -13,4 +13,8 @@ public final class DateHelper {
calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime(); return calendar.getTime();
} }
public static int getUnixTime(Date localDateTime){
return (int)(localDateTime.getTime() / 1000L);
}
} }
...@@ -19,7 +19,7 @@ public final class Language { ...@@ -19,7 +19,7 @@ public final class Language {
* @return A language instance. * @return A language instance.
*/ */
public static Language getLanguage(String langCode) { public static Language getLanguage(String langCode) {
return new Language(langCode + ".json", Grasscutter.getConfig().DefaultLanguage.toLanguageTag()); return new Language(langCode + ".json", Grasscutter.getConfig().DefaultLanguage.toLanguageTag() + ".json");
} }
/** /**
...@@ -46,15 +46,20 @@ public final class Language { ...@@ -46,15 +46,20 @@ public final class Language {
private Language(String fileName, String fallback) { private Language(String fileName, String fallback) {
@Nullable JsonObject languageData = null; @Nullable JsonObject languageData = null;
InputStream file = Grasscutter.class.getResourceAsStream("/languages/" + fileName);
if (file == null) { // Provided fallback language.
file = Grasscutter.class.getResourceAsStream("/languages/" + fallback);
Grasscutter.getLogger().warn("Failed to load language file: " + fileName + ", falling back to: " + fallback);
}
if(file == null) { // Fallback the fallback language.
file = Grasscutter.class.getResourceAsStream("/languages/en-US.json");
Grasscutter.getLogger().warn("Failed to load language file: " + fallback + ", falling back to: en-US.json");
}
if(file == null)
throw new RuntimeException("Unable to load the primary, fallback, and 'en-US' language files.");
try { try {
InputStream file = Grasscutter.class.getResourceAsStream("/languages/" + fileName); languageData = Grasscutter.getGsonFactory().fromJson(Utils.readFromInputStream(file), JsonObject.class);
String translationContents = Utils.readFromInputStream(file);
if(translationContents.equals("empty")) {
file = Grasscutter.class.getResourceAsStream("/languages/" + fallback);
translationContents = Utils.readFromInputStream(file);
}
languageData = Grasscutter.getGsonFactory().fromJson(translationContents, JsonObject.class);
} catch (Exception exception) { } catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to load language file: " + fileName, exception); Grasscutter.getLogger().warn("Failed to load language file: " + fileName, exception);
} }
......
...@@ -312,6 +312,9 @@ ...@@ -312,6 +312,9 @@
"success": "Teleported %s to %s, %s, %s in scene %s", "success": "Teleported %s to %s, %s, %s in scene %s",
"description": "Change the player's position." "description": "Change the player's position."
}, },
"tower": {
"unlock_done": "Abyss Corridor's Floors are all unlocked now."
},
"weather": { "weather": {
"usage": "Usage: weather <weatherId> [climateId]", "usage": "Usage: weather <weatherId> [climateId]",
"success": "Changed weather to %s with climate %s", "success": "Changed weather to %s with climate %s",
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
} }
}, },
"status": { "status": {
"free_software": "Grasscutter 是免费开源软件,遵循Apache-2.0 license。如果您是付费购买的,那您已经被骗了。项目地址:Github:https://github.com/Grasscutters/Grasscutter", "free_software": "Grasscutter 是免费开源软件,遵循AGPL-3.0 license。如果您是付费购买的,那您已经被骗了。项目地址:Github:https://github.com/Grasscutters/Grasscutter",
"starting": "正在启动 Grasscutter...", "starting": "正在启动 Grasscutter...",
"shutdown": "正在关闭...", "shutdown": "正在关闭...",
"done": "加载完成!输入 \"help\" 查看命令列表", "done": "加载完成!输入 \"help\" 查看命令列表",
......
...@@ -24,4 +24,6 @@ ...@@ -24,4 +24,6 @@
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</root> </root>
<logger name="emu.grasscutter.scripts.ScriptLib" level="DEBUG">
</logger>
</Configuration> </Configuration>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment