New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to Broadcast games on the Local Area Network #3828
Conversation
…o the local area network. JoinGameScreen.java - Added the broadcast button to be enabled only when the server is not broadcasting.
Can one of the admins please verify this patch? |
CC @DarkWeird |
It's wip now? |
@DarkWeird I added the Button for the broadcast but when I run the game it does not show up , am I missing something ? |
I am not familiar with NUI. |
engine/src/main/java/org/terasology/rendering/nui/layers/mainMenu/JoinGameScreen.java
Outdated
Show resolved
Hide resolved
Don't forget cleanup resources (shutdown executor on exit) |
Yes adding it :)
With respect to integration with integration with network subsytem, this is already separate module isn't it ?
Yeah it does not break anything for now, Do I need to take care of something specific ?
Working on the headless server part, |
I think better implement as part of network system, or near. Your broadcast placed at nui's package now :3 |
This pull request introduces 1 alert when merging 835c573 into 6671bf5 - view on LGTM.com new alerts:
|
Added a translation for the broadcast and terminate broadcast features also closed the executor thread after termination.
|
maybe use UPnP or something? |
I am not sure what DI stuff, could you explain what do you mean ?
We could do this , it is a much brute force approach and only checks for 255 machines.
|
I guess this is very susceptible to attacks, it is a bit of a dangerous approach ? |
properly configured UPnP isn't any more risky than UDP broadcast. improperly configured UPnP doesn't suddenly become more dangerous because apps are using it. improperly configured UPnP is inherently dangerous, but doesn't affect the safety of terasology. whether UPnP is properly or improperly configured depends on the router, not on terasology. |
Maybe, some problem will be with docker, vpn, etc. With all what generate virtual network interfaces, if it installed/used on system |
@SoniEx2 i think implemention of UPnP can be as separate PR. Hmm, broadcast to WAN ? |
Please read up on UPnP https://en.wikipedia.org/wiki/Universal_Plug_and_Play It is a more suitable solution to this problem. |
Thank you so much for the feedback, really appreciate it. Will Read up on this. |
@DarkWeird Looking at the dependency injection, rather I left it to the class to be responsible for the creation for the object. It would work fine, if i hard code the object creation, If you suggest that is a better approach, I am definitely on board :) |
// ----------------------------------------- // | ||
StringBuffer discoveryMessage = new StringBuffer(); | ||
discoveryMessage.append("M-SEARCH * HTTP/1.1\r\n"); | ||
discoveryMessage.append("HOST: " + ssdpIP + ":" + ssdpPort + "\r\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks to be sufficient in order to broadcast both the port and address.
This methods using system default encoding (windows-125* on windows, utf-8 on linux(or any other encoding, if user has very interesting ideas :) )). Further, it has not zero chance to use different, non equals encoding. Oh, java encoding called as charset. My(and many libraries authors) recommendation: explicitly use UTF-8 ( new String(bytes, charset), getBytes(charset)) |
@DarkWeird I added the encoding. Thanks |
engine/src/main/java/org/terasology/network/BroadCastServer.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/network/BroadCastServer.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/rendering/nui/layers/mainMenu/JoinGameScreen.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/rendering/nui/layers/mainMenu/JoinGameScreen.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/rendering/nui/layers/mainMenu/JoinGameScreen.java
Outdated
Show resolved
Hide resolved
private DatagramSocket getReceiveSocket() { | ||
try { | ||
if (receiveSocket == null) { | ||
receiveSocket = new DatagramSocket(8002, | ||
InetAddress.getByName("0.0.0.0")); // 0.0.0.0 for listen to all ips | ||
receiveSocket.setBroadcast(true); | ||
} | ||
} catch (Exception e) { | ||
logger.error("Broadcast Exception Encountered" + e.getMessage()); | ||
} | ||
return receiveSocket; | ||
} | ||
|
||
private DatagramSocket getSendSocket() { | ||
try { | ||
if (sendSocket == null) { | ||
sendSocket = new DatagramSocket(8001, InetAddress.getLocalHost()); | ||
sendSocket.setBroadcast(true); | ||
} | ||
} catch (Exception e) { | ||
logger.error("Broadcast Exception Encountered" + e.getMessage()); | ||
} | ||
return sendSocket; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In these methods:
If sockets cannot to create(e.g. ports already binded), you will receive NullPointerException, because methods will return null at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't be needing a new socket right? Because we would be using the same one to send the request. Do you think there is a better way to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm would do separate socket intialization and getters, because it can throw exception.
If it will throw exception, then broadcast feature cannot will work properly at least.
If you will use one class instance - you use one socket.
Additional, You can split client and server functionality
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback but in my opinion this code should catch broadcast errors if the sockets are null or the ports are unavailable so that the broadcast can be terminated immediately. I do not think we need more modularity in terms of client and server functionality because this offers us the best error handling.
engine/src/main/java/org/terasology/network/BroadCastServer.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/rendering/nui/layers/mainMenu/JoinGameScreen.java
Outdated
Show resolved
Hide resolved
@DarkWierd got most of the changes committed :) |
@sladyn98 I don't think what PR done. |
Yeah this was something I was waiting for feedback on. Do we want to build a separate area for displaying the servers or just show up on the JoinGameScreen.? |
engine/src/main/java/org/terasology/network/BroadCastServer.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/org/terasology/network/BroadCastServer.java
Outdated
Show resolved
Hide resolved
Better separate area with something like 'LAN' title. Or something like separate Tab (if it is possible). |
Should this PR involve the development of a new UI component, since the IP addresses for the broadcast would anyway show up in the Join game section. What do you guys think ? |
IMHO I would try to just finish out this PR at its current level of functionality so we can merge it and start fresh with a second effort involving the UI. This has been an awesome PR but the longer one keeps going the more unwieldy the PR gets and the higher the risk of code going stale / conflicting with changes made in the meantime. Small relatively quick PRs ftw - although some topics to warrant some deeper review and some extra effort cycles :-) |
Cool @DarkWeird This looks done to me then ? |
Gentle Ping @DarkWeird @Cervator Can we get this over the line :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason the main menu translation was broken when testing this PR. Not sure where this comes from, though.
When I click the "Join Game Screen" my game just crashes with this error:
23:34:15.553 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#game-settings'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#start-singleplayer-game'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#host-multiplayer-game'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#join-game-online'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#game-settings'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#extras-label'
23:34:15.558 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#exit-game'
23:34:15.563 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#non-native-jvm-warn'
23:34:16.053 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#storage-service'
23:34:16.053 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#storage-service-logged-out'
23:34:16.053 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#select-game-title'
23:34:16.058 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#select-singleplayer-game-sub-title'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#world-generator'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-list'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#create-game'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#load-game'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#delete-game'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#save-game-details'
23:34:16.068 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#back'
23:34:16.073 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#save-game-path'
23:34:16.078 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#new-game-title'
23:34:16.078 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#select-singleplayer-game-sub-title'
23:34:16.078 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#game-name'
23:34:16.078 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#gameplay'
23:34:16.083 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#return-main-menu'
23:34:16.083 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#start-playing'
23:34:16.083 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#back'
23:34:16.083 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#advanced'
23:34:16.093 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#advanced-game-setup'
23:34:16.093 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#warn-modules'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#world-seed'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-filter'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#disable-all-modules'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-name'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-version-installed'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-version-available'
23:34:16.098 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-status'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#activate-module'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#download-module'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#game-details-module-details'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#select-modules-filter-reset'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#return-basic-setup'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#continue-universe-setup'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#return-main-menu'
23:34:16.103 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#start-playing'
23:34:16.108 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#load-delay-warning'
23:34:16.153 [main] WARN o.t.engine.internal.TimeBase - Delta too great (10644), capping to 1000
23:34:16.158 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#storage-service'
23:34:16.158 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#storage-service-token-not-present'
23:34:16.162 [main] INFO o.t.logic.console.ConsoleImpl - [NOTIFICATION] ?storage-service?: ?storage-service-token-not-present?
23:34:23.582 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#settings-title'
23:34:23.584 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#player-settings'
23:34:23.584 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#video-settings'
23:34:23.584 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#audio-settings'
23:34:23.584 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#input-settings'
23:34:23.585 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#back'
23:34:25.466 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#audio-settings-title'
23:34:25.467 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#sound-volume'
23:34:25.469 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#music-volume'
23:34:25.469 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#back'
23:34:35.734 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#join-server-title'
23:34:35.735 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#listed-servers'
23:34:35.736 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#custom-servers'
23:34:35.736 [main] WARN o.t.rendering.nui.asset.UIFormat - Field 'defaultCard' not recognized for interface org.terasology.rendering.nui.UIWidget in {"type":"CardLayout","id":"cards","defaultCard":"onlineServerListScrollArea","contents":[{"type":"RelativeLayout","id":"customServerListScrollArea","contents":[{"type":"ScrollableArea","content":{"type":"UIList","id":"customServerList","family":"module-list"},"layoutInfo":{"position-top":{"target":"TOP"},"position-bottom":{"target":"TOP","widget":"edit","offset":8}}},{"type":"UIButton","id":"edit","text":"${engine:menu#edit-server}","layoutInfo":{"use-content-height":true,"width":135,"position-bottom":{"target":"TOP","widget":"add","offset":8}}},{"type":"UIButton","id":"remove","text":"${engine:menu#remove-server}","layoutInfo":{"use-content-height":true,"position-left":{"target":"RIGHT","widget":"edit","offset":8},"position-bottom":{"target":"TOP","widget":"add","offset":8}}},{"type":"UIButton","id":"add","text":"${engine:menu#add-server}","layoutInfo":{"use-content-height":true,"position-bottom":{"target":"BOTTOM"}}}]},{"type":"RelativeLayout","id":"onlineServerListScrollArea","contents":[{"type":"ScrollableArea","content":{"type":"UIList","id":"onlineServerList","family":"module-list"},"layoutInfo":{"position-top":{"target":"TOP"},"position-bottom":{"target":"TOP","widget":"download","offset":4}}},{"type":"UILabel","id":"download","text":"<download info text>","layoutInfo":{"use-content-height":true,"position-bottom":{"target":"BOTTOM","offset":4}}}]}],"layoutInfo":{"position-top":{"target":"BOTTOM","widget":"serverTypeRow"},"position-bottom":{"target":"BOTTOM"}}}
23:34:35.737 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#edit-server'
23:34:35.737 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#remove-server'
23:34:35.737 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#add-server'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#server-name'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#server-owner'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#server-address'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#server-port'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#ping'
23:34:35.738 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#online-players'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#game-worlds'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#module-list'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#join-server-refresh'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#join-server-action'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#join-server-broadcast'
23:34:35.739 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#back'
23:34:35.869 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#enter-username-message'
23:34:35.870 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#dialog-ok'
23:34:35.870 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#dialog-cancel'
23:34:35.885 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#parsing-content'
23:34:35.885 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#parsing-content'
23:34:35.887 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#parsing-content'
23:34:35.887 [main] WARN o.t.i18n.TranslationSystemImpl - No translation for 'engine:menu#parsing-content'
23:34:35.890 [main] ERROR o.terasology.engine.TerasologyEngine - Uncaught exception, attempting clean game shutdown
java.lang.NullPointerException: null
at org.terasology.rendering.nui.layers.mainMenu.JoinGameScreen$8.get(JoinGameScreen.java:359)
at org.terasology.rendering.nui.layers.mainMenu.JoinGameScreen$8.get(JoinGameScreen.java:356)
at org.terasology.rendering.nui.widgets.UIButton.onDraw(UIButton.java:152)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.layouts.RowLayout.onDraw(RowLayout.java:136)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.layouts.relative.RelativeLayout.onDraw(RelativeLayout.java:85)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.layouts.ColumnLayout.onDraw(ColumnLayout.java:191)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.layouts.relative.RelativeLayout.onDraw(RelativeLayout.java:85)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.CoreScreenLayer.onDraw(CoreScreenLayer.java:211)
at org.terasology.rendering.nui.internal.CanvasImpl.drawStyledWidget(CanvasImpl.java:425)
at org.terasology.rendering.nui.internal.CanvasImpl.drawWidget(CanvasImpl.java:411)
at org.terasology.rendering.nui.internal.NUIManagerInternal.render(NUIManagerInternal.java:509)
at org.terasology.engine.modes.StateMainMenu.render(StateMainMenu.java:210)
at org.terasology.engine.subsystem.lwjgl.LwjglGraphics.postUpdate(LwjglGraphics.java:166)
at org.terasology.engine.TerasologyEngine.tick(TerasologyEngine.java:471)
at org.terasology.engine.TerasologyEngine.mainLoop(TerasologyEngine.java:425)
at org.terasology.engine.TerasologyEngine.run(TerasologyEngine.java:401)
at org.terasology.engine.Terasology.main(Terasology.java:162)
23:34:35.891 [main] INFO o.terasology.engine.TerasologyEngine - Shutting down Terasology...
I didn't look into the details further as I could not test it properly. One thing I noticed is that you don't make use of the Closeable
sockets, e.g., use try-with-resources. That may simplify the creation and closing of the sockets in your code.
private static boolean turnOnBroadcast; | ||
private static final Logger logger = LoggerFactory.getLogger(BroadCastServer.class); | ||
private final String discoveryRequest = "DISCOVERY_REQUEST"; | ||
private final String discoveryResponse = "DISCOVERY_RESPONSE"; | ||
private DatagramSocket receiveSocket; | ||
private DatagramSocket sendSocket; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would order these members differently. First the static final fields (the string constants can also be final I would think), second the static members, and finally the class members.
The string constants should then be written in all-caps.
private static boolean turnOnBroadcast; | |
private static final Logger logger = LoggerFactory.getLogger(BroadCastServer.class); | |
private final String discoveryRequest = "DISCOVERY_REQUEST"; | |
private final String discoveryResponse = "DISCOVERY_RESPONSE"; | |
private DatagramSocket receiveSocket; | |
private DatagramSocket sendSocket; | |
private static final Logger logger = LoggerFactory.getLogger(BroadCastServer.class); | |
private static final String DISCOVERY_REQUEST= "DISCOVERY_REQUEST"; | |
private static final String DISCOVERY_RESPONSE = "DISCOVERY_RESPONSE"; | |
private static boolean turnOnBroadcast; | |
private DatagramSocket receiveSocket; | |
private DatagramSocket sendSocket; |
|
||
|
||
public boolean isBroadCastTurnedOn() { | ||
return turnOnBroadcast; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use active as word here? BroadCastServer.isActive()
may be a bit more intuitive.
BroadCastServer.turnOnBroadcast = true; | ||
try { | ||
sendBroadCast(); | ||
Executors.newSingleThreadExecutor().execute(new Runnable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use a lambda expression for the runnable here.
@@ -92,6 +85,9 @@ | |||
@In | |||
private StorageServiceWorker storageServiceWorker; | |||
|
|||
@In | |||
private BroadCastServer broadCastServer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BroadCastServer
is just a regular class without any annotations or such. Thus, I don't think it can just be injected like this.
broadCastServerButton.bindText(new ReadOnlyBinding<String>() { | ||
@Override | ||
public String get() { | ||
if (!broadCastServer.isBroadCastTurnedOn()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case broadCastServer
cannot be injected this will be null
, leading to a NullPointerException. That probably breaks the UI screen then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sladyn98 please make sure that your changes are working locally for you. If you're adding new buttons or adjusting the UI it's always a good idea to include screenshots of the changes/how it should look like.
Hey @sladyn98, are you still around? Please do continue work on this and ask questions if you're still interested in this. Otherwise, I'm going to close this PR due to inactivity. |
I could fork this tbh |
@SoniEx2 be our guest 🙃 broadcasting games in the local network would be a nice feature 🤓 |
@SoniEx2 @skaldarnar I am so sorry guys, I do not think I can complete this feature, I am working with Jenkins for GSoC 2020 and I feel really bad for leaving this code incomplete. TBH it took a lot more than I initially expected, :) but I enjoyed working on it. Thanks for the reviews |
Thanks for the heads up @sladyn98 - closing this PR (for now). |
Ability to Broadcast games on the Local Area Network
Contains
JoinGameScreen.java
- Added the broadcast button to be enabled only when the server is not broadcasting, along with a custom message of all the modules, ports and IpAddresse'sBroadcast.java
- Added the ability to broadcast the game on all local listening servers.The message is broadcasted every 5 minutes.
"Fixes #3760"
How to test
The broadcast button is added to the User Interface and the respective broadcasted message can be read on the Join Game Server on a machine present on the LAN.
Outstanding before merging