![]() |
|
#1
|
|||
|
|||
![]()
Seems to be some kind of problem with relative paths
Long shot but try running the dedicated server through strace. For example: strace -e open <name of the dedicated server executable> that will print a line for every file the dedicated server tries to open. |
#2
|
||||
|
||||
![]()
Pfeil, thanks for taking an interest! The relevant code is as follows:
Server path chooser; this is a javafx.stage.FileChooser instance, which returns a java.io.File object. The UI objects are retrieved from a map of controls by key and "file" is bound to the results of showing the file chooser dialog using the .showOpenDialog method (this is all that is in ui/show-chooser). This is just to keep the UI and the application logic separate. The file is then converted to an absolute path String using File.getCanonicalPath. Code:
(defn server-choose-command "### server-choose-command This zero argument function displays the server chooser dialog and uses the provided file to set the server path in the UI." [] (let [{:keys [server-chooser server-path-lbl]} @state/controls file (ui/show-chooser server-chooser)] (when file (ui/set-label server-path-lbl (.getCanonicalPath file))))) Code:
(defn server-path-select [] (let [{:keys [server-path-lbl]} @state/controls server-path (ui/get-text server-path-lbl)] (if (= server-path "...") (reset! state/server-path nil) (reset! state/server-path server-path)))) Code:
(defn get-text "### get-text This one argument function returns the text from the supplied control." ^String [control] (.getText control)) Code:
(defn set-single-remote [] (let [{:keys [single-path-fld single-path-lbl]} @state/controls mission-path (ui/get-text single-path-fld)] (when (not (string/blank? mission-path)) (ui/set-label single-path-lbl mission-path)))) Code:
(defn set-label "### set-label This two argument function sets the text content of the supplied control to the value of the supplied text argument." [^Label label text] (.setText label text)) Code:
(defn single-choose-command [] (let [{:keys [mis-chooser single-path-lbl]} @state/controls file (ui/show-chooser mis-chooser)] (when file (ui/set-label single-path-lbl (get-resolved-path @state/server-path (.getCanonicalPath file)))))) Then the path is relativized against the missions directory, normalised to remove any redundant elements and converted to a String object, before replacing all backward slash characters with forward slash characters. The Clojure function str calls the .toString method for x when it is given the single object x. The methods used for canonisation and relativisation can be found in java.nio.file.Path. Code:
(defn get-resolved-path [root-path in-path] (let [path (Paths/get in-path (into-array [""])) server-path (Paths/get root-path (into-array [""])) server-dir (.getParent server-path) mis-dir (.resolve server-dir "Missions")] (string/replace (->> path (.relativize mis-dir) .normalize str) "\\" "/"))) This is the same global state atom update logic as with the server chooser, triggered by an InvalidationListener attached to the Label object: Code:
(defn single-path-select [] (let [{:keys [single-path-lbl]} @state/controls single-path (ui/get-text single-path-lbl)] (if (= single-path "...") (reset! state/mission-path nil) (reset! state/mission-path single-path)))) Code:
(defn load-unload-command "### load-unload-command This is a zero argument function which unloads the currently loaded mission if it is loaded." [] (if @state/loaded (server/unload-mission) (when (= @state/mode "single") (ui/toggle-prog-ind @state/controls true) (server/load-mission @state/mission-path)))) Code:
(defn unload-mission "### unload-mission This is a zero argument function which sends the command to the server console which unloads the current mission. Because the unload command doesn't return any output on completion, we also request the mission state so that the state parsers can register the change in mission status." [] (write-socket "mission DESTROY") (get-mission-state)) Code:
(defn load-mission "### load-mission This is a one argument function which sends the command to the server console which loads a mission using the path described by the argument." [path-to-mission] (write-socket (str "mission LOAD " path-to-mission))) Code:
(defn write-socket "### write-socket This is a single argument function that simply calls the println method of the object that is stored in the socket-out atom using the argument that we provide. This atom should contain the instance of the PrintWriter object that is instantiated when we successfully connect to the server." [text] (.println ^PrintWriter @socket-out text)) Code:
(.print @socket-out (str text "\\n")) (.flush @socket-out) Output stream definition here: Code:
(reset! socket-out (PrintWriter. (BufferedWriter. (OutputStreamWriter. (.getOutputStream ^Socket @socket) (Charset/forName "UTF-8"))) true)) Hope this is a decent enough outline of what goes on (I'm not cagey about the code as I intend to open the repo to all once the basic feature set is complete). One of the methods that I used to try and detect any differences in the path was to set a comparator function on the single-choose-command function using clojure.data/diff, which compared the text content of the single mission path TextField to the return value of the get-resolved-path function. I loaded the mission using the TextField, loaded a different mission using the chooser (to trigger the bug), then loaded the original mission from the TextField using the FileChooser. In every instance it indicated that the value in the TextField (which worked every time) was the same as that returned by the FileChooser (which didn't), i.e. it returned (nil nil "Net/dogfight/DCG/dcgmission.mis"). The_WOZ, I will give your suggestion a try once I get home, thanks! Last edited by TheGrunch; 02-17-2014 at 09:55 PM. Reason: corrections |
#3
|
||||
|
||||
![]()
The_WOZ, output was as follows:
Code:
% env WINEPREFIX=/home/david/Servers/il2-4.12/ strace -eopen wineconsole --backend=curses /home/david/Servers/il2-4.12/drive_d/il2server/il2server.exe open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib64/libtinfo.so.5", O_RDONLY) = 3 open("/lib64/libdl.so.2", O_RDONLY) = 3 open("/lib64/libc.so.6", O_RDONLY) = 3 open("/dev/tty", O_RDWR|O_NONBLOCK) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 open("/proc/meminfo", O_RDONLY) = 3 open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3 open("/usr/bin/wineconsole", O_RDONLY) = 3 --- SIGCHLD (Child exited) @ 0 (0) --- [ Process PID=761 runs in 32 bit mode. ] open("/etc/ld.so.cache", O_RDONLY) = 3 open("/usr/lib/libwine.so.1", O_RDONLY) = 3 open("/lib/libpthread.so.0", O_RDONLY) = 3 open("/lib/libc.so.6", O_RDONLY) = 3 open("/lib/libdl.so.2", O_RDONLY) = 3 open("/usr/bin/wine", O_RDONLY) = 3 open("/lib/ld-linux.so.2", O_RDONLY) = 3 open("/etc/ld.so.cache", O_RDONLY) = 3 open("/usr/lib/libwine.so.1", O_RDONLY) = 3 open("/lib/libpthread.so.0", O_RDONLY) = 3 open("/lib/libc.so.6", O_RDONLY) = 3 open("/lib/libdl.so.2", O_RDONLY) = 3 open("/usr/lib/wine/ntdll.dll.so", O_RDONLY) = 3 open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/libm.so.6", O_RDONLY) = 3 open(".", O_RDONLY|O_LARGEFILE) = 3 open("/etc/nsswitch.conf", O_RDONLY) = 4 open("/etc/ld.so.cache", O_RDONLY) = 4 open("/lib/libnss_files.so.2", O_RDONLY) = 4 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 4 --- SIGCHLD (Child exited) @ 0 (0) --- open("/proc/cpuinfo", O_RDONLY|O_LARGEFILE) = 6 open("/usr/lib/wine/kernel32.dll.so", O_RDONLY) = 6 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 6 open("/proc/ide", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/proc/scsi/scsi", O_RDONLY|O_LARGEFILE) = 6 open("/home/david/Servers/il2-4.12/dosdevices/z:/home/david", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 9 open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 9 open(".", O_RDONLY|O_LARGEFILE) = 13 open(".", O_RDONLY|O_LARGEFILE) = 13 open(".", O_RDONLY|O_LARGEFILE) = 13 open("/usr/lib/wine/wineconsole.exe.so", O_RDONLY) = 9 open("/home/david/Servers/il2-4.12/dosdevices/c:/windows/syswow64", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 9 open("/usr/lib/wine/advapi32.dll.so", O_RDONLY) = 9 --- SIGCHLD (Child exited) @ 0 (0) --- open("/etc/ld.so.cache", O_RDONLY) = 9 open("/lib/libncurses.so.5", O_RDONLY) = 9 open("/lib/libtinfo.so.5", O_RDONLY) = 9 open("/usr/share/terminfo/x/xterm", O_RDONLY|O_LARGEFILE) = 9 open("/proc/meminfo", O_RDONLY) = 9 open("/usr/share/terminfo/x/xterm", O_RDONLY|O_LARGEFILE) = 10 |
#4
|
|||
|
|||
![]()
Seems I can't be of much help I'm afraid. While I get the basic gist of what you're doing, Java isn't my cup of tea, shall we say.
Something that did occur to me: Have you tried running the server from a windows machine? Perhaps Wine is somehow "translating" one way or the other, and getting it wrong the first time. When you compared packets in Wireshark, did you compare the first and second packet sent using the file selection dialog, or the difference(lack thereof) between textbox and dialog? |
#5
|
||||
|
||||
![]()
Hi Pfeil,
I tried both, and it seems I can't find any difference in either output. ![]() I haven't tried running the server from a Windows machine and it's quite possible that this is the culprit. However, I would still want to solve the issue as it's my main platform for running the server personally. ![]() Server interaction: Code:
public class Command { @Inject Connection connection; @Inject public void sendCommand(String line) { connection.getOutput().println(line); connection.getOutput().flush(); if (connection.getOutput().checkError()) { System.out.println("Not sent."); } } public void loadMission(String mission) { sendCommand("mission LOAD " + mission); } public void endMission() { sendCommand("mission DESTROY"); } public void askMission() { sendCommand("mission"); } } Code:
public void connect() { try { socket = new Socket(Config.getIpAddress(), Integer.decode(Config.getPort())); output = new PrintWriter(socket.getOutputStream(), true); input = new BufferedReader(new InputStreamReader(socket.getInputStream(), Charset.forName("UTF-8"))); setConnected(true); if (socket.isConnected()) { System.out.println("Connected to server " + Config.getIpAddress() + " on port " + Config.getPort()); } } catch (IOException e) { setConnected(false); System.out.println("Failed to connect to socket."); e.printStackTrace(); } } Code:
public void serverPathButtonAction() { String serverPath; File file = serverChooser.showOpenDialog(new Stage()); if (file != null) { serverPath = file.toString(); Config.setServerPath(serverPath); serverPathLabel.setText(serverPath); missionPathButton.setDisable(false); } else { serverPathLabel.setText("<no server .exe selected>"); missionPathButton.setDisable(true); } } public void missionPathButtonAction() { String missionPath; File file = missionChooser.showOpenDialog(new Stage()); if (file != null) { missionPath = file.toString(); Config.setMissionPath(missionPath); missionPathLabel.setText(missionPath); } else { missionPathLabel.setText("<no .mis file selected>"); } } Code:
public String resolveMissionPath() { Path serverPath; Path missionPath; Path missionsRoot; Path missionLoadPath; String missionLoadString; serverPath = Paths.get(Config.getServerPath()); missionPath = Paths.get(Config.getMissionPath()); missionsRoot = serverPath.getParent().resolve("Missions"); missionLoadPath = missionsRoot.relativize(missionPath).normalize(); missionLoadString = missionLoadPath.toString().replace("\\", "/"); return missionLoadString; } Code:
public void startStopButtonAction() { if (Mission.getMissionRunning()) { command.endMission(); command.askMission(); } else { if (Config.getRemoteMode()) { command.loadMission(Config.getRemotePath()); } else { command.loadMission(mainConfigPresenter.resolveMissionPath()); } } }
Just tried using all of these with no luck. ![]() |
#6
|
|||
|
|||
![]() Quote:
Try loading missions both ways, then a second time from the file chooser. Then look in the output from strace, if the open path for the .mis file differs. |
![]() |
Thread Tools | |
Display Modes | |
|
|