Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
*.iml
/mapsync/
/data/
.vscode/
**/.factorypath
server/package-lock.json
server/yarn.lock

16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [


{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
}
]
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "interactive"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -37,7 +38,7 @@ public static MapSyncMod getMod() {
return INSTANCE;
}

private static final KeyMapping openGuiKey = new KeyMapping(
public static final KeyMapping openGuiKey = new KeyMapping(
"key.map-sync.openGui",
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_COMMA,
Expand Down Expand Up @@ -101,7 +102,8 @@ public void handleRespawn(ClientboundRespawnPacket packet) {
* only null when not connected to a server
*/
public @Nullable ServerConfig getServerConfig() {
final ServerData currentServer = Minecraft.getInstance().getCurrentServer();
final Minecraft instance = Minecraft.getInstance();
final ServerData currentServer = instance.getCurrentServer();
if (currentServer == null) {
serverConfig = null;
return null;
Expand Down
26 changes: 17 additions & 9 deletions mod/common/src/main/java/gjum/minecraft/mapsync/common/ModGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.NotNull;

import java.util.List;
Expand All @@ -27,7 +27,7 @@ public class ModGui extends Screen {
Button syncServerConnectBtn;

public ModGui(Screen parentScreen) {
super(new TextComponent("Map-Sync"));
super(Component.literal("Map-Sync"));
this.parentScreen = parentScreen;
}

Expand All @@ -50,15 +50,17 @@ protected void init() {
right - 100,
top,
100, 20,
new TextComponent("Close"),
Component.literal("Close"),
button -> minecraft.setScreen(parentScreen)));

final Minecraft gameInstance = Minecraft.getInstance();

if (serverConfig != null) {
if (serverConfig != null && !gameInstance.isLocalServer()) {
addWidget(syncServerAddressField = new EditBox(font,
left,
top + 40,
innerWidth - 110, 20,
new TextComponent("Sync Server Address")));
Component.literal("Sync Server Address")));
syncServerAddressField.setMaxLength(256);
syncServerAddressField.setValue(String.join(" ",
serverConfig.getSyncServerAddresses()));
Expand All @@ -67,7 +69,7 @@ protected void init() {
right - 100,
top + 40,
100, 20,
new TextComponent("Connect"),
Component.literal("Connect"),
this::connectClicked));
}
} catch (Throwable e) {
Expand All @@ -91,12 +93,18 @@ public void connectClicked(Button btn) {
@Override
public void render(@NotNull PoseStack poseStack, int i, int j, float f) {
try {
renderBackground(poseStack);
drawCenteredString(poseStack, font, title, width / 2, top, 0xFFFFFF);

Minecraft gameInstance = Minecraft.getInstance();
if (gameInstance.isLocalServer()) {
drawCenteredString(poseStack, font, "Map-Sync only runs with proper servers!", width/2, 2 * top, 0xFFFFFF);
return;
}

// wait for init() to finish
if (syncServerAddressField == null) return;
if (syncServerConnectBtn == null) return;

renderBackground(poseStack);
drawCenteredString(poseStack, font, title, width / 2, top, 0xFFFFFF);
syncServerAddressField.render(poseStack, i, j, f);

var dimensionState = getMod().getDimensionState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,16 @@ protected void onHandleBlockDestruction(ClientboundBlockDestructionPacket packet
}
}

@Inject(method = "handleBlockBreakAck", at = @At("RETURN"))
protected void onHandleBlockBreakAck(ClientboundBlockBreakAckPacket packet, CallbackInfo ci) {
@Inject(method = "handleBlockChangedAck", at = @At("RETURN"))
protected void onHandleBlockChangedAck(ClientboundBlockChangedAckPacket packet, CallbackInfo ci) {
return;
/* It seems like 1.19 cannot figure the fuck out what this event is???
if (!Minecraft.getInstance().isSameThread()) return; // will be called again on mc thread in a moment
try {
BlockPos pos = packet.pos();
getMod().handleMcChunkPartialChange(pos.getX() >> 4, pos.getZ() >> 4);
} catch (Throwable e) {
printErrorRateLimited(e);
}
}*/
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
import org.jetbrains.annotations.Nullable;

import javax.crypto.*;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.security.spec.MGF1ParameterSpec;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -267,7 +270,7 @@ void setUpEncryption(ChannelHandlerContext ctx, ClientboundEncryptionRequestPack
encrypt(packet.publicKey, sharedSecret),
encrypt(packet.publicKey, packet.verifyToken)));
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException |
IllegalBlockSizeException e) {
IllegalBlockSizeException | InvalidAlgorithmParameterException e) {
shutDown();
throw new RuntimeException(e);
}
Expand All @@ -283,9 +286,11 @@ void setUpEncryption(ChannelHandlerContext ctx, ClientboundEncryptionRequestPack
}
}

private static byte[] encrypt(PublicKey key, byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
private static byte[] encrypt(PublicKey key, byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding"); // RSA_PKCS1_PADDING is no longer supported for private decryption
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth switching to websockets (#43) and letting TLS do all the encryption, though this does add complexity in terms of self-signed certs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you run map sync behind a reverse proxy, (as should be the recommended setup anyway,) self signed certs become less of an issues especially with many featuring lets encrypt integration, or highly popular tooling around that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, but it also adds more complexity to server setup: the client will no-doubt expect to connect to a wss:// target, but running the server directly would not produce a wss:// target to connect to, which likely means a higher reliance on docker (or similar), which is not particularly noob-friendly. And this is MapSync, we shouldn't expect our users to be highly technically literate. Setting up a MapSync server should be as easy as running those OTT executables that were handed out to people stuck in Wholefoods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean that's a somewhat noble goal, I just feel like its unrealistic that many will run the server at all. Who knows though, if that is the case for whatever reason, we could always embed a lets encrypt library and do it all ourselves.

Copy link
Contributor

@Protonull Protonull Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just seems like a bit of a zero-sum game to do it like that: switching to websockets makes development easier since encryption and packet framing is all done for you, but requiring a third-party reverse proxy makes server setup and maintenance more difficult for our users. If it's a choice between the two, I say we choose ease of use. But if we are still keen on using websockets, we could automatically generate a self-signed cert if the configuration doesn't already specify a pre-existing one. That way we wont be spamming Let's Encrypt anytime someone spins up a development server.

// https://docs.openssl.org/master/man3/RSA_public_encrypt/#description
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-1", "MGF1", new MGF1ParameterSpec("SHA-1"), PSource.PSpecified.DEFAULT);
cipher.init(Cipher.ENCRYPT_MODE, key, oaepParams);
return cipher.doFinal(data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import gjum.minecraft.mapsync.common.MapSyncMod;
import gjum.minecraft.mapsync.common.ModGui;
import net.minecraft.client.KeyMapping;
import net.minecraftforge.client.ClientRegistry;
import net.minecraftforge.client.ConfigGuiHandler;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
Expand Down Expand Up @@ -36,8 +36,8 @@ public void clientSetup(FMLClientSetupEvent event) {

// Register hook for the mod list
ModLoadingContext.get().registerExtensionPoint(
ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory(
ConfigScreenHandler.ConfigScreenFactory.class,
() -> new ConfigScreenHandler.ConfigScreenFactory(
(minecraft, previousScreen) -> new ModGui(previousScreen)
)
);
Expand All @@ -56,6 +56,12 @@ public void onClientTick(TickEvent.ClientTickEvent event) {

@Override
public void registerKeyBinding(KeyMapping mapping) {
ClientRegistry.registerKeyBinding(mapping);
return;
// ClientRegistry.registerKeyBinding(mapping);
}

@SubscribeEvent
public static void registerKeyMappingsEvent(RegisterKeyMappingsEvent event) {
event.register(ForgeMapSyncMod.openGuiKey);
}
}
14 changes: 7 additions & 7 deletions mod/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx2048M

archives_base_name=MapSync
maven_group=gjum.minecraft.mapsync
mod_version=2.0.1-1.18.2
mod_version=2.0.1-1.19.2
mod_display_name=MapSync
mod_description=Share map data with your friends, live, and privately.
mod_authors=Gjum,Protonull,okx,Huskydog9988,specificlanguage,SirAlador,klaribot
Expand All @@ -11,14 +11,14 @@ mod_home_url=https://github.com/CivPlatform/map-sync
mod_source_url=https://github.com/CivPlatform/map-sync
mod_issues_url=https://github.com/CivPlatform/map-sync/issues

minecraft_version=1.18.2
minecraft_version=1.19.2
# https://parchmentmc.org/docs/getting-started
parchment_version=2022.11.06
parchment_version=2022.11.27
enabled_platforms=fabric,forge

# https://fabricmc.net/versions.html
fabric_loader_version=0.15.10
fabric_api_version=0.77.0+1.18.2
fabric_loader_version=0.15.11
fabric_api_version=0.77.0+1.19.2

forge_version=1.18.2-40.2.0
forge_major_version=40
forge_version=1.19.2-43.3.2
forge_major_version=43
2 changes: 2 additions & 0 deletions mod/temp.update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
./gradlew -PUPDATE_SRGS="https://gist.githubusercontent.com/amadornes/e00ea624b3cccc84fbca0800f651b546/raw/raw_mappings.tsrg;https://gist.githubusercontent.com/SizableShrimp/882a671ff74256d150776da08c89ef72/raw/forge_1.19_renames.tsrg" updateEverything

4 changes: 2 additions & 2 deletions server/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const SUPPORTED_VERSIONS = new Set([
"2.0.1-1.18.2+fabric",
"2.0.1-1.18.2+forge",
"2.0.1-1.19.2+fabric",
"2.0.1-1.19.2+forge",
]);

// SHA1 produces 160-bit (20-byte) hashes
Expand Down
2 changes: 1 addition & 1 deletion server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class TcpServer {
return crypto.privateDecrypt(
{
key: this.keyPair.privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
},
buf,
);
Expand Down
Loading