├── .github
└── workflows
│ ├── gradle.yml
│ └── publish.yml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── STYLEGUIDE.md
├── build.gradle
├── examples
├── build.gradle
└── src
│ └── main
│ └── java
│ └── io
│ └── tlf
│ └── monkeynetty
│ └── test
│ ├── JmeClient.java
│ ├── JmeServer.java
│ └── messages
│ ├── TestSerializableDataA.java
│ ├── TestSerializableDataB.java
│ ├── TestTCPBigMessageA.java
│ ├── TestTCPBigMessageB.java
│ ├── TestTCPMessage.java
│ ├── TestUDPBigMessageA.java
│ ├── TestUDPBigMessageB.java
│ └── TestUDPMessage.java
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── monkey-netty
├── build.gradle
└── src
│ └── main
│ └── java
│ └── io
│ └── tlf
│ └── monkeynetty
│ ├── ConnectionListener.java
│ ├── MessageListener.java
│ ├── NetworkClient.java
│ ├── NetworkMessageDecoder.java
│ ├── NetworkMessageEncoder.java
│ ├── NetworkMessageException.java
│ ├── NetworkObjectInputStream.java
│ ├── NetworkObjectOutputStream.java
│ ├── NetworkProtocol.java
│ ├── NetworkRegistrar.java
│ ├── NetworkServer.java
│ ├── client
│ ├── DatagramPacketObjectDecoder.java
│ ├── MessageCacheMode.java
│ └── NettyClient.java
│ ├── msg
│ ├── ConnectionEstablishedMessage.java
│ ├── NetworkMessage.java
│ ├── PingMessage.java
│ └── UdpConHashMessage.java
│ └── server
│ ├── NettyConnection.java
│ ├── NettyServer.java
│ ├── UdpChannel.java
│ └── UdpServerChannel.java
├── publishing
└── publishing.gradle
└── settings.gradle
/.github/workflows/gradle.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Gradle
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
3 |
4 | name: Java CI with Gradle
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up JDK 1.8
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: 1.8
23 | - name: Grant execute permission for gradlew
24 | run: chmod +x gradlew
25 | - name: Build with Gradle
26 | run: ./gradlew build
27 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish package to GitHub Packages
2 | on:
3 | release:
4 | types: [created]
5 | jobs:
6 | publish:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 | - uses: actions/setup-java@v1
11 | with:
12 | java-version: 1.8
13 | - name: Publish package
14 | run: gradle publish
15 | env:
16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .shelf/
3 | /.gradle/
4 | /.gradle/*
5 | /.nb-gradle/
6 | /.nb-gradle/*
7 | /build/*
8 | /build/**/
9 | .nb-*
10 | .class
11 | nbproject/private/
12 | bin/
13 | libs/
14 | build/
15 | .gradle
16 | .gradletasknamecache
17 | /publishing/publishing.properties
18 | *.asc
19 | *.gpg
20 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | #### v0.1.2
2 | * Artifacts now published to Maven Central (#35)
3 | * Update Netty.IO to v4.1.82.Final
4 | * Update jMonkeyEngine to v3.5.2
5 |
6 | #### v0.1.1
7 | * Fixed concurrency issues with Collections (#31)
8 | * Updated Netty.IO to version 4.1.58 (#29)
9 | * Updated Gradle to version 6.8.1 (#30)
10 |
11 | #### v0.1.0
12 | * SSL Support for TCP channel (#5, #6)
13 | * Optimize network message transport (#4, #11)
14 | * Better logging and enhanced test examples (#9)
15 | * Better error reporting on non-serializable objects in a message (#14, #16)
16 | * Separation of examples and library, and corresponding dependencies (#22)
17 | * Fixed issue where messages would be transferred before connection listeners were notified (#20, #21)
18 | * Fixed issue where dropped sockets would not be detected (#10, #23)
19 |
20 | #### V0.0.0
21 | Initial Release
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Liquid Crystal Studios Contribution Guide
2 |
3 | ## Code Style
4 | [Style Guide](STYLEGUIDE.md)
5 |
6 | ## Branches
7 | When developing, one must create a branch and then submit a merge request when finished with the branch.
8 | There are two types of branches that are acceptable.
9 |
10 | ### Working Branches
11 | A branch labeled `working-[username]` can be used when making changed that are not related to an issue. An example of such branch is: `working-trevorflynn`, this would indicate that Trevor Flynn has created this branch.
12 | Not all working branches will get accepted when a merge request is accepted.
13 | A branch will not be accepted when:
14 | * Conflicts with master branch
15 | * Does not pass pipeline build
16 | * Does not provide any contribution
17 | * Contains improperly formatted code
18 | * Contains a feature or fix that was not approved.
19 |
20 | ### Issue Branches
21 | When working on an issue or feature that is documented in issues, a branch must be created and its name must start with the ID of the issue.
22 | An example would be if someone was fixing issue #45, an error. Then the branch name must start with 45. i.e. `45-fix-for-some-error`
23 | A merge request must be made before the branch will be merged with the master branch.
24 | A branch will not be accepted when:
25 | * Conflicts with master branch
26 | * Does not pass pipeline build
27 | * Does not provide any contribution
28 | * Contains improperly formatted code
29 | * Contains a feature or fix that was not approved.
30 |
31 | ### The Master Branch
32 | The master branch is the current development branch that all work will be merged into.
33 |
34 | ### Production Branches
35 | A production branch will deploy the application.
36 | The branch must be named: `[release issue #]-release-v[version]`
37 | Example: `33-release-v0.1.1`
38 |
39 | ## Issues
40 |
41 | ### Tagging
42 | If you find a bug, security exploit, or feature. Please create an issue with the appropriate tags.
43 | Do not attach the `issue` tag to something that is not a bug or security exploit.
44 | Do not attach the `feature` tag to something that is not a possible feature or enhancement.
45 | Do not attach a group tage such as `front-end` or `back-end` to an issue that does not pertain to the group.
46 | Do not attach a `review` or `second-opinion` tag to issues that do not need feedback from Trevor Flynn or Jayce Miller respectively.
47 | Attach a code tag if the issue pertains to a type of code. For example, if there is an issue inside of the database, attach the `database` tag.
48 |
49 | ### Assigning
50 | Do not assign an issue to someone other than yourself.
51 | Do not assign on issue to yourself if you are not going to work on it.
52 | (The above rules do not seem to apply to Trevor Flynn...)
53 |
54 | ### Closing
55 | Do not close an issue unless it is agreed that it should be closed, or until the issue is resolved.
56 |
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Trevor Flynn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # monkey-netty
2 | 
3 | An implementation of a server-client communication system for jMonkeyEngine using Netty.IO that utilizes
4 | both TCP and UDP communication.
5 |
6 | **Checkout our [Wiki](https://github.com/tlf30/monkey-netty/wiki) for getting started.**
7 |
8 | **See example for server and client in `examples` module.**
9 |
10 | ## Installing with Gradle
11 | Note: We will no longer be publishing packages to GitHub, future packages will be in Maven Central.
12 | In your `build.gradle` you will need to:
13 |
14 | ```groovy
15 | dependencies {
16 | ...
17 | implementation 'io.tlf.monkeynetty:monkey-netty:0.1.2-SNAPSHOT'
18 | }
19 | ```
20 |
21 | ## Installing with Maven
22 | Note: We will no longer be publishing packages to GitHub, future packages will be in Maven Central.
23 | In your pom.xml you will need to:
24 |
25 | ```xml
26 |
27 | ...
28 |
29 | io.tlf.monkeynetty
30 | monkey-netty
31 | 0.1.2-SNAPSHOT
32 |
33 |
34 | ```
35 |
36 |
--------------------------------------------------------------------------------
/STYLEGUIDE.md:
--------------------------------------------------------------------------------
1 | Liquid Crystal Studios' Java Style Guide
2 |
3 | ## Coding style
4 |
5 | ### Formatting
6 |
7 | #### Use line breaks wisely
8 | There are generally two reasons to insert a line break:
9 |
10 | 1. Your statement exceeds the column limit.
11 |
12 | 2. You want to logically separate a thought.
13 | Writing code is like telling a story. Written language constructs like chapters, paragraphs,
14 | and punctuation (e.g. semicolons, commas, periods, hyphens) convey thought hierarchy and
15 | separation. We have similar constructs in programming languages; you should use them to your
16 | advantage to effectively tell the story to those reading the code.
17 |
18 | #### Indent style
19 | We use the "one true brace style" ([1TBS](http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS)).
20 | Indent size is 4 columns.
21 |
22 | ```
23 | // Like this.
24 | if (x < 0) {
25 | negative(x);
26 | } else {
27 | nonnegative(x);
28 | }
29 |
30 | // Not like this.
31 | if (x < 0)
32 | negative(x);
33 |
34 | // Also not like this.
35 | if (x < 0) negative(x);
36 | ```
37 |
38 | Continuation indent is 8 columns. Nested continuations may add 8 columns or 4 at each level.
39 |
40 | ```
41 | // Bad.
42 | // - Line breaks are arbitrary.
43 | // - Scanning the code makes it difficult to piece the message together.
44 | throw new IllegalStateException("Failed to process request" + request.getId()
45 | + " for user " + user.getId() + " query: '" + query.getText()
46 | + "'");
47 |
48 | // Good.
49 | // - Each component of the message is separate and self-contained.
50 | // - Adding or removing a component of the message requires minimal reformatting.
51 | throw new IllegalStateException("Failed to process"
52 | + " request " + request.getId()
53 | + " for user " + user.getId()
54 | + " query: '" + query.getText() + "'");
55 | ```
56 |
57 | Don't break up a statement unnecessarily.
58 |
59 | ```
60 | // Bad.
61 | final String value =
62 | otherValue;
63 |
64 | // Good.
65 | final String value = otherValue;
66 | ```
67 |
68 | Method declaration continuations.
69 |
70 | ```
71 | // Sub-optimal since line breaks are arbitrary and only filling lines.
72 | String downloadAnInternet(Internet internet, Tubes tubes,
73 | Blogosphere blogs, Amount bandwidth) {
74 | tubes.download(internet);
75 | ...
76 | }
77 |
78 | // Acceptable.
79 | String downloadAnInternet(Internet internet, Tubes tubes, Blogosphere blogs,
80 | Amount bandwidth) {
81 | tubes.download(internet);
82 | ...
83 | }
84 |
85 | // Nicer, as the extra newline gives visual separation to the method body.
86 | String downloadAnInternet(Internet internet, Tubes tubes, Blogosphere blogs,
87 | Amount bandwidth) {
88 |
89 | tubes.download(internet);
90 | ...
91 | }
92 |
93 | // Preferred for easy scanning and extra column space.
94 | public String downloadAnInternet(
95 | Internet internet,
96 | Tubes tubes,
97 | Blogosphere blogs,
98 | Amount bandwidth) {
99 |
100 | tubes.download(internet);
101 | ...
102 | }
103 |
104 | ```
105 |
106 | ##### Chained method calls
107 |
108 | ```
109 | // Bad.
110 | // - Line breaks are based on line length, not logic.
111 | Iterable modules = ImmutableList.builder().add(new LifecycleModule())
112 | .add(new AppLauncherModule()).addAll(application.getModules()).build();
113 |
114 | // Better.
115 | // - Calls are logically separated.
116 | // - However, the trailing period logically splits a statement across two lines.
117 | Iterable modules = ImmutableList.builder().
118 | add(new LifecycleModule()).
119 | add(new AppLauncherModule()).
120 | addAll(application.getModules()).
121 | build();
122 |
123 | // Good.
124 | // - Method calls are isolated to a line.
125 | // - The proper location for a new method call is unambiguous.
126 | Iterable modules = ImmutableList.builder()
127 | .add(new LifecycleModule())
128 | .add(new AppLauncherModule())
129 | .addAll(application.getModules())
130 | .build();
131 | ```
132 |
133 | #### Only tabs
134 | All indentation must be done with tabs.
135 |
136 | #### CamelCase for types and classes, camelCase for variables, UPPER_SNAKE for constants, lowercase for packages.
137 |
138 | #### No trailing whitespace
139 | Trailing whitespace characters, while logically benign, add nothing to the program.
140 | However, they do serve to frustrate developers when using keyboard shortcuts to navigate code.
141 |
142 | ### Field, class, and method declarations
143 |
144 | ##### Modifier order
145 |
146 | We follow the [Java Language Specification](http://docs.oracle.com/javase/specs/) for modifier
147 | ordering (sections
148 | [8.1.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.1),
149 | [8.3.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1) and
150 | [8.4.3](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.3)).
151 |
152 | ```
153 | // Bad.
154 | final volatile private String value;
155 |
156 | // Good.
157 | private final volatile String value;
158 | ```
159 |
160 | ### Variable naming
161 |
162 | #### Extremely short variable names should be reserved for instances like loop indices.
163 |
164 | ```
165 | // Bad.
166 | // - Field names give little insight into what fields are used for.
167 | class User {
168 | private final int a;
169 | private final String m;
170 |
171 | ...
172 | }
173 |
174 | // Good.
175 | class User {
176 | private final int ageInYears;
177 | private final String maidenName;
178 |
179 | ...
180 | }
181 | ```
182 |
183 | #### Don't embed metadata in variable names
184 | A variable name should describe the variable's purpose. Adding extra information like scope and
185 | type is generally a sign of a bad variable name.
186 |
187 | Avoid embedding the field type in the field name.
188 |
189 | ```
190 | // Bad.
191 | Map idToUserMap;
192 | String valueString;
193 |
194 | // Good.
195 | Map usersById;
196 | String value;
197 | ```
198 |
199 | Also avoid embedding scope information in a variable. Hierarchy-based naming suggests that a class
200 | is too complex and should be broken apart.
201 |
202 | ```
203 | // Bad.
204 | String _value;
205 | String mValue;
206 |
207 | // Good.
208 | String value;
209 | ```
210 |
211 | ### Space pad operators and equals.
212 |
213 | ```
214 | // Bad.
215 | // - This offers poor visual separation of operations.
216 | int foo=a+b+1;
217 |
218 | // Good.
219 | int foo = a + b + 1;
220 | ```
221 |
222 | ### Be explicit about operator precedence
223 | Don't make your reader open the
224 | [spec](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html) to confirm,
225 | if you expect a specific operation ordering, make it obvious with parenthesis.
226 |
227 | ```
228 | // Bad.
229 | return a << 8 * n + 1 | 0xFF;
230 |
231 | // Good.
232 | return (a << (8 * n) + 1) | 0xFF;
233 | ```
234 |
235 | It's even good to be *really* obvious.
236 |
237 | ```
238 | if ((values != null) && (10 > values.size())) {
239 | ...
240 | }
241 | ```
242 |
243 | ### Always include scope
244 | ```
245 | // Bad.
246 | class MyClass {
247 | ...
248 | }
249 |
250 | // Good.
251 | protected MyClass {
252 | ...
253 | }
254 |
255 | ```
256 | ### Documentation
257 |
258 | The more visible a piece of code is (and by extension - the farther away consumers might be),
259 | the more documentation is needed.
260 |
261 | #### "I'm writing a report about..."
262 | Your elementary school teacher was right - you should never start a statement this way.
263 | Likewise, you shouldn't write documentation this way.
264 |
265 | ```
266 | // Bad.
267 | /**
268 | * This is a class that implements a cache. It does caching for you.
269 | */
270 | class Cache {
271 | ...
272 | }
273 |
274 | // Good.
275 | /**
276 | * A volatile storage for objects based on a key, which may be invalidated and discarded.
277 | */
278 | class Cache {
279 | ...
280 | }
281 | ```
282 |
283 | #### Documenting a class
284 | Documentation for a class may range from a single sentence
285 | to paragraphs with code examples. Documentation should serve to disambiguate any conceptual
286 | blanks in the API, and make it easier to quickly and *correctly* use your API.
287 | A thorough class doc usually has a one sentence summary and, if necessary,
288 | a more detailed explanation.
289 |
290 | ```
291 | /**
292 | * An RPC equivalent of a unix pipe tee. Any RPC sent to the tee input is guaranteed to have
293 | * been sent to both tee outputs before the call returns.
294 | *
295 | * @param The type of the tee'd service.
296 | */
297 | public class RpcTee {
298 | ...
299 | }
300 | ```
301 |
302 | #### Documenting a method
303 | A method doc should tell what the method *does*. Depending on the argument types, it may
304 | also be important to document input format.
305 |
306 | ```
307 | // Bad.
308 | // - The doc tells nothing that the method declaration didn't.
309 | // - This is the 'filler doc'. It would pass style checks, but doesn't help anybody.
310 | /**
311 | * Splits a string.
312 | *
313 | * @param s A string.
314 | * @return A list of strings.
315 | */
316 | List split(String s);
317 |
318 | // Better.
319 | // - We know what the method splits on.
320 | // - Still some undefined behavior.
321 | /**
322 | * Splits a string on whitespace.
323 | *
324 | * @param s The string to split. An {@code null} string is treated as an empty string.
325 | * @return A list of the whitespace-delimited parts of the input.
326 | */
327 | List split(String s);
328 |
329 | // Great.
330 | // - Covers yet another edge case.
331 | /**
332 | * Splits a string on whitespace. Repeated whitespace characters are collapsed.
333 | *
334 | * @param s The string to split. An {@code null} string is treated as an empty string.
335 | * @return A list of the whitespace-delimited parts of the input.
336 | */
337 | List split(String s);
338 | ```
339 |
340 | #### Be professional
341 | We've all encountered frustration when dealing with other libraries, but ranting about it doesn't
342 | do you any favors. Suppress the expletives and get to the point.
343 |
344 | ```
345 | // Bad.
346 | // I hate xml/soap so much, why can't it do this for me!?
347 | try {
348 | userId = Integer.parseInt(xml.getField("id"));
349 | } catch (NumberFormatException e) {
350 | ...
351 | }
352 |
353 | // Good.
354 | // TODO: Tuck field validation away in a library.
355 | try {
356 | userId = Integer.parseInt(xml.getField("id"));
357 | } catch (NumberFormatException e) {
358 | ...
359 | }
360 | ```
361 |
362 | #### Don't document overriding methods (usually)
363 |
364 | ```
365 | public interface Database {
366 | /**
367 | * Gets the installed version of the database.
368 | *
369 | * @return The database version identifier.
370 | */
371 | String getVersion();
372 | }
373 |
374 | // Bad.
375 | // - Overriding method doc doesn't add anything.
376 | public class PostgresDatabase implements Database {
377 | /**
378 | * Gets the installed version of the database.
379 | *
380 | * @return The database version identifier.
381 | */
382 | @Override
383 | public String getVersion() {
384 | ...
385 | }
386 | }
387 |
388 | // Good.
389 | public class PostgresDatabase implements Database {
390 | @Override
391 | public int getVersion();
392 | }
393 |
394 | // Great.
395 | // - The doc explains how it differs from or adds to the interface doc.
396 | public class TwitterDatabase implements Database {
397 | /**
398 | * Semantic version number.
399 | *
400 | * @return The database version in semver format.
401 | */
402 | @Override
403 | public String getVersion() {
404 | ...
405 | }
406 | }
407 | ```
408 |
409 | #### Use javadoc features
410 |
411 | ##### No author tags
412 | Code can change hands numerous times in its lifetime, and quite often the original author of a
413 | source file is irrelevant after several iterations. We find it's better to trust commit
414 | history.
415 |
416 | An exception to this is usually found in classes or functions written specificly by Trevor Flynn or Jayce Miller.
417 |
418 | ### Imports
419 |
420 | #### Import ordering
421 | Imports are grouped by top-level package, with blank lines separating groups.
422 |
423 | ```
424 | import java.*
425 | import javax.*
426 |
427 | import scala.*
428 |
429 | import com.*
430 |
431 | import net.*
432 |
433 | import org.*
434 |
435 | import com.twitter.*
436 |
437 | import static *
438 | ```
439 |
440 | #### No wildcard imports
441 | Wildcard imports make the source of an imported class less clear. They also tend to hide a high
442 | class [fan-out](http://en.wikipedia.org/wiki/Coupling_(computer_programming)#Module_coupling).
443 | *See also [texas imports](#stay-out-of-texas)*
444 |
445 | ```
446 | // Bad.
447 | // - Where did Foo come from?
448 | import com.twitter.baz.foo.*;
449 | import com.twitter.*;
450 |
451 | interface Bar extends Foo {
452 | ...
453 | }
454 |
455 | // Good.
456 | import com.twitter.baz.foo.BazFoo;
457 | import com.twitter.Foo;
458 |
459 | interface Bar extends Foo {
460 | ...
461 | }
462 | ```
463 | The exception to this is when working with junit assertions (static imports), awt or swing classes.
464 |
465 | ### Use annotations wisely
466 |
467 | #### @Nullable
468 | This only applies to projects that are using null protection.
469 | By default - disallow `null`. When a variable, parameter, or method return value may be `null`,
470 | be explicit about it by marking
471 | [@Nullable](http://code.google.com/p/jsr-305/source/browse/trunk/ri/src/main/java/javax/annotation/Nullable.java?r=24).
472 | This is advisable even for fields/methods with private visibility.
473 |
474 | ```
475 | class Database {
476 | @Nullable private Connection connection;
477 |
478 | @Nullable
479 | Connection getConnection() {
480 | return connection;
481 | }
482 |
483 | void setConnection(@Nullable Connection connection) {
484 | this.connection = connection;
485 | }
486 | }
487 | ```
488 |
489 | ### TODOs
490 |
491 | #### Leave TODOs early and often
492 | A TODO isn't a bad thing - it's signaling a future developer (possibly yourself) that a
493 | consideration was made, but omitted for various reasons. It can also serve as a useful signal when
494 | debugging.
495 |
496 | ### Comments
497 |
498 | #### Leave comments often
499 | It often is much more clear what a snippet of code is doing when a short comment explains it.
500 |
501 | ```
502 | // Good.
503 | //Add mesh to world
504 | world.getApplication().enqueue(() -> {
505 | if (markedForRebuild.get()) {
506 | destroyGeometry(this.chunkGeometry);
507 | this.chunkGeometry = newGeom;
508 | this.chunkNode.attachChild(chunkGeometry);
509 | world.fireChunkRebuilt(this, edited);
510 | this.edited = false;
511 | } else {
512 | this.chunkGeometry = newGeom;
513 | this.chunkNode.attachChild(newGeom);
514 | }
515 | if (Outside.IS_CLIENT) {
516 | chunkGeometry.addControl(new ChunkLod(this));
517 | }
518 | });
519 | ```
520 |
521 | #### Don't leave dead code commented out
522 | Leaving dead code commented out can offten confuse other programmers who go to work on the code latter.
523 | ```
524 | // Bad.
525 | HashMap data = componentImporter.importComponent("world_" + worldName);
526 | if (data == null) {
527 | return new HashSet<>();
528 | }
529 | long id = Long.parseLong(data.get("id").toString());
530 | //Script[] scriptData = result.getObject("scripts", Script[].class);
531 | Chunk[] sqlChunks = ((ArrayList) data.get("chunks")).toArray(new Chunk[0]);
532 | ChunkMeta[] chunks = new ChunkMeta[sqlChunks.length];
533 | ```
534 | One exception to this is when a todo is left to indicate to another programmer what needs to happen with the code:
535 | ```
536 | // Good.
537 | HashMap data = componentImporter.importComponent("world_" + worldName);
538 | if (data == null) {
539 | return new HashSet<>();
540 | }
541 | long id = Long.parseLong(data.get("id").toString());
542 | //Script[] scriptData = result.getObject("scripts", Script[].class); //TODO: Currently we have no way of attaching scripts to the world
543 | Chunk[] sqlChunks = ((ArrayList) data.get("chunks")).toArray(new Chunk[0]);
544 | ChunkMeta[] chunks = new ChunkMeta[sqlChunks.length];
545 | ``
546 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
3 | }
4 |
5 | allprojects {
6 | version = '0.1.2-SNAPSHOT'
7 | group = "io.tlf.monkeynetty"
8 |
9 | ext {
10 | //Dependency Versions
11 | jmeVersion = "3.5.2-stable"
12 | jmeGroup = "org.jmonkeyengine"
13 | nettyioVersion = "4.1.82.Final"
14 | }
15 |
16 | repositories {
17 | mavenCentral()
18 | }
19 | }
20 |
21 | apply from: 'publishing/publishing.gradle'
22 |
--------------------------------------------------------------------------------
/examples/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 | dependencies {
6 | implementation project(":monkey-netty")
7 | implementation jmeGroup + ':jme3-desktop:' + jmeVersion
8 | implementation jmeGroup + ':jme3-lwjgl3:' + jmeVersion
9 | }
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/JmeClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty.test;
26 |
27 | import io.netty.handler.logging.LogLevel;
28 | import io.tlf.monkeynetty.ConnectionListener;
29 | import io.tlf.monkeynetty.test.messages.TestUDPBigMessageA;
30 | import io.tlf.monkeynetty.test.messages.TestTCPBigMessageA;
31 | import io.tlf.monkeynetty.test.messages.TestTCPMessage;
32 | import io.tlf.monkeynetty.test.messages.TestUDPMessage;
33 | import com.jme3.app.SimpleApplication;
34 | import com.jme3.input.KeyInput;
35 | import com.jme3.input.controls.ActionListener;
36 | import com.jme3.input.controls.KeyTrigger;
37 | import io.tlf.monkeynetty.MessageListener;
38 | import io.tlf.monkeynetty.NetworkClient;
39 | import io.tlf.monkeynetty.NetworkServer;
40 | import io.tlf.monkeynetty.client.NettyClient;
41 | import io.tlf.monkeynetty.msg.NetworkMessage;
42 | import io.tlf.monkeynetty.test.messages.TestTCPBigMessageB;
43 | import io.tlf.monkeynetty.test.messages.TestUDPBigMessageB;
44 |
45 | /**
46 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
47 | */
48 | public class JmeClient extends SimpleApplication {
49 |
50 | NettyClient client;
51 |
52 | @Override
53 | public void simpleInitApp() {
54 | client = new NettyClient("test", true, 10000, "localhost");
55 | stateManager.attach(client);
56 | client.setLogLevel(LogLevel.INFO);
57 | client.registerListener(new MessageListener() {
58 | @Override
59 | public void onMessage(NetworkMessage msg, NetworkServer server, NetworkClient client) {
60 | System.out.println("Got message " + msg);
61 | }
62 |
63 | @Override
64 | public Class extends NetworkMessage>[] getSupportedMessages() {
65 | return new Class[]{TestTCPMessage.class, TestUDPMessage.class, TestTCPBigMessageA.class, TestTCPBigMessageB.class, TestUDPBigMessageA.class, TestUDPBigMessageB.class};
66 | }
67 | });
68 |
69 | client.registerListener(new ConnectionListener() {
70 | @Override
71 | public void onConnect(NetworkClient client) {
72 | client.send(new TestTCPMessage());
73 | }
74 |
75 | @Override
76 | public void onDisconnect(NetworkClient client) {
77 |
78 | }
79 | });
80 | inputManager.addMapping("enter", new KeyTrigger(KeyInput.KEY_RETURN));
81 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
82 | if (isPressed) {
83 | client.send(new TestTCPMessage());
84 | }
85 | }, "enter");
86 | inputManager.addMapping("space", new KeyTrigger(KeyInput.KEY_SPACE));
87 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
88 | if (isPressed) {
89 | client.send(new TestUDPMessage());
90 | }
91 | }, "space");
92 | //todo: replace with setup protocol, when feature https://github.com/tlf30/monkey-netty/issues/7 will be solved
93 | inputManager.addMapping("key1", new KeyTrigger(KeyInput.KEY_1));
94 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
95 | if (isPressed) {
96 | client.send(new TestTCPBigMessageA());
97 | }
98 | }, "key1");
99 | inputManager.addMapping("key2", new KeyTrigger(KeyInput.KEY_2));
100 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
101 | if (isPressed) {
102 | client.send(new TestUDPBigMessageA());
103 | }
104 | }, "key2");
105 | inputManager.addMapping("key3", new KeyTrigger(KeyInput.KEY_3));
106 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
107 | if (isPressed) {
108 | client.send(new TestTCPBigMessageB());
109 | }
110 | }, "key3");
111 | inputManager.addMapping("key4", new KeyTrigger(KeyInput.KEY_4));
112 | inputManager.addListener((ActionListener) (name, isPressed, tpf) -> {
113 | if (isPressed) {
114 | client.send(new TestUDPBigMessageB());
115 | }
116 | }, "key4");
117 | }
118 |
119 | int frame = 0;
120 |
121 | @Override
122 | public void simpleUpdate(float tpf) {
123 | if (frame < 10) {
124 | client.send(new TestTCPMessage());
125 | frame++;
126 | }
127 | }
128 |
129 | public static void main(String[] args) {
130 |
131 | JmeClient client = new JmeClient();
132 | client.start();
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/JmeServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty.test;
26 |
27 | import io.tlf.monkeynetty.test.messages.TestTCPMessage;
28 | import io.tlf.monkeynetty.test.messages.TestUDPMessage;
29 | import com.jme3.app.SimpleApplication;
30 | import com.jme3.system.JmeContext;
31 | import io.netty.handler.logging.LogLevel;
32 | import io.tlf.monkeynetty.ConnectionListener;
33 | import io.tlf.monkeynetty.MessageListener;
34 | import io.tlf.monkeynetty.NetworkClient;
35 | import io.tlf.monkeynetty.NetworkServer;
36 | import io.tlf.monkeynetty.msg.NetworkMessage;
37 | import io.tlf.monkeynetty.server.NettyServer;
38 | import io.tlf.monkeynetty.test.messages.TestTCPBigMessageA;
39 | import io.tlf.monkeynetty.test.messages.TestTCPBigMessageB;
40 | import io.tlf.monkeynetty.test.messages.TestUDPBigMessageA;
41 | import io.tlf.monkeynetty.test.messages.TestUDPBigMessageB;
42 |
43 | /**
44 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
45 | */
46 | public class JmeServer extends SimpleApplication {
47 |
48 | @Override
49 | public void simpleInitApp() {
50 | NettyServer server = new NettyServer("test", true, 10000);
51 | server.setLogLevel(LogLevel.INFO);
52 | stateManager.attach(server);
53 | server.registerListener(new ConnectionListener() {
54 | @Override
55 | public void onConnect(NetworkClient client) {
56 | System.out.println("Client connected: " + client.getAddress());
57 | }
58 |
59 | @Override
60 | public void onDisconnect(NetworkClient client) {
61 | System.out.println("Client disconnected: " + client.getAddress());
62 | }
63 | });
64 | server.registerListener(new MessageListener() {
65 | @Override
66 | public void onMessage(NetworkMessage msg, NetworkServer server, NetworkClient client) {
67 | System.out.println("Got message " + msg.getName() + " from client " + client.getAddress());
68 | System.out.println(msg.toString());
69 | client.send(msg);
70 | }
71 |
72 | @Override
73 | public Class extends NetworkMessage>[] getSupportedMessages() {
74 | return new Class[] {TestUDPMessage.class, TestTCPMessage.class, TestTCPBigMessageA.class, TestTCPBigMessageB.class, TestUDPBigMessageA.class, TestUDPBigMessageB.class};
75 | }
76 | });
77 | }
78 |
79 | public static void main(String[] args) {
80 | JmeServer server = new JmeServer();
81 | server.start(JmeContext.Type.Headless);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestSerializableDataA.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import java.io.Serializable;
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | /**
31 | * @author Radosław K
32 | *
33 | * Class used for message testing purpose, it will check:
34 | * - if Serializable Object within message will work correctly
35 | * - if default Java Serializable class will not cause issue
36 | */
37 | public class TestSerializableDataA implements Serializable {
38 |
39 | public List list;
40 |
41 | public TestSerializableDataA() {
42 | list = new ArrayList<>();
43 | for (long i = 0; i < 10; i++) {
44 | list.add(i);
45 | }
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return list.toString();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestSerializableDataB.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import java.io.Serializable;
27 | import java.util.ArrayList;
28 | import java.util.Arrays;
29 | import java.util.HashMap;
30 | import java.util.Random;
31 |
32 | /**
33 | * @author Radosław K
34 | *
35 | * Class used for message testing purpose, it will check:
36 | * - if Serializable Object within message will work correctly
37 | * - if private fields will not cause issues
38 | * - if multiple depth primitives/Classes will work correctly.
39 | */
40 | public class TestSerializableDataB implements Serializable {
41 |
42 | private HashMap map = new HashMap<>();
43 |
44 | public TestSerializableDataB() {
45 | map.put("test1", 12);
46 | map.put("test2", "TestString");
47 | map.put("test2", "TestVal" + (new Random().nextFloat() * 1000));
48 | map.put("test3", new int[]{34,3245,534543,2233});
49 | map.put("test4", new ArrayList<>(Arrays.asList("TestValue1", "TestValue2", "TestValue3")));
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return map.toString();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestTCPBigMessageA.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import io.tlf.monkeynetty.NetworkProtocol;
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Radosław K
31 | *
32 | * Message used for testing nested Serializable objects within message
33 | */
34 | public class TestTCPBigMessageA implements NetworkMessage {
35 |
36 | private final TestSerializableDataA objectA;
37 |
38 | public TestTCPBigMessageA() {
39 | objectA = new TestSerializableDataA();
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return "Test TCP Big Message A";
45 | }
46 |
47 | @Override
48 | public NetworkProtocol getProtocol() {
49 | return NetworkProtocol.TCP;
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return objectA.toString();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestTCPBigMessageB.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import io.tlf.monkeynetty.NetworkProtocol;
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Radosław K
31 | *
32 | * Message used for testing nested Serializable objects within message
33 | */
34 | public class TestTCPBigMessageB implements NetworkMessage {
35 |
36 | private final TestSerializableDataB objectB;
37 |
38 | public TestTCPBigMessageB() {
39 | objectB = new TestSerializableDataB();
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return "Test TCP Big Message B";
45 | }
46 |
47 | @Override
48 | public NetworkProtocol getProtocol() {
49 | return NetworkProtocol.TCP;
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return objectB.toString();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestTCPMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty.test.messages;
26 |
27 | import io.tlf.monkeynetty.NetworkProtocol;
28 | import io.tlf.monkeynetty.msg.NetworkMessage;
29 |
30 | /**
31 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
32 | */
33 | public class TestTCPMessage implements NetworkMessage {
34 |
35 | private int someValue;
36 |
37 | @Override
38 | public String getName() {
39 | return "Test TCP Message";
40 | }
41 |
42 | @Override
43 | public NetworkProtocol getProtocol() {
44 | return NetworkProtocol.TCP;
45 | }
46 |
47 | public int getSomeValue() {
48 | return someValue;
49 | }
50 |
51 | public void setSomeValue(int someValue) {
52 | this.someValue = someValue;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestUDPBigMessageA.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import io.tlf.monkeynetty.NetworkProtocol;
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Radosław K
31 | *
32 | * Message used for testing nested Serializable objects within message
33 | */
34 | public class TestUDPBigMessageA implements NetworkMessage {
35 |
36 | private final TestSerializableDataA objectA;
37 |
38 | public TestUDPBigMessageA() {
39 | objectA = new TestSerializableDataA();
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return "Test UDP Big Message A";
45 | }
46 |
47 | @Override
48 | public NetworkProtocol getProtocol() {
49 | return NetworkProtocol.UDP;
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return objectA.toString();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestUDPBigMessageB.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2020 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty.test.messages;
25 |
26 | import io.tlf.monkeynetty.NetworkProtocol;
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Radosław K
31 | *
32 | * Message used for testing nested Serializable objects within message
33 | */
34 | public class TestUDPBigMessageB implements NetworkMessage {
35 |
36 | private final TestSerializableDataB objectB;
37 |
38 | public TestUDPBigMessageB() {
39 | objectB = new TestSerializableDataB();
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return "Test UDP Big Message B";
45 | }
46 |
47 | @Override
48 | public NetworkProtocol getProtocol() {
49 | return NetworkProtocol.UDP;
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return objectB.toString();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/tlf/monkeynetty/test/messages/TestUDPMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty.test.messages;
26 |
27 | import io.tlf.monkeynetty.NetworkProtocol;
28 | import io.tlf.monkeynetty.msg.NetworkMessage;
29 |
30 | /**
31 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
32 | */
33 | public class TestUDPMessage implements NetworkMessage {
34 |
35 | private String someValue;
36 |
37 | @Override
38 | public String getName() {
39 | return "Test UDP Message";
40 | }
41 |
42 | @Override
43 | public NetworkProtocol getProtocol() {
44 | return NetworkProtocol.UDP;
45 | }
46 |
47 | public String getSomeValue() {
48 | return someValue;
49 | }
50 |
51 | public void setSomeValue(String someValue) {
52 | this.someValue = someValue;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tlf30/monkey-netty/318598262566551e21960855f07fe09cce4dad89/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 |
88 | @rem Execute Gradle
89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
90 |
91 | :end
92 | @rem End local scope for the variables with windows NT shell
93 | if "%ERRORLEVEL%"=="0" goto mainEnd
94 |
95 | :fail
96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
97 | rem the _cmd.exe /c_ return code!
98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
99 | exit /b 1
100 |
101 | :mainEnd
102 | if "%OS%"=="Windows_NT" endlocal
103 |
104 | :omega
105 |
--------------------------------------------------------------------------------
/monkey-netty/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java-library'
3 | id 'maven-publish'
4 | }
5 |
6 | ext {
7 | PUBLISH_GROUP_ID = group
8 | PUBLISH_VERSION = version
9 | PUBLISH_ARTIFACT_ID = name
10 | }
11 |
12 | task javadocJar(type: Jar) {
13 | classifier = 'javadoc'
14 | from javadoc
15 | }
16 |
17 | task sourcesJar(type: Jar) {
18 | classifier = 'sources'
19 | from sourceSets.main.allSource
20 | }
21 |
22 | artifacts {
23 | archives javadocJar, sourcesJar
24 | }
25 |
26 | dependencies {
27 | //Jme3
28 | api jmeGroup + ':jme3-core:' + jmeVersion
29 | //Netty.IO
30 | api group: 'io.netty', name: 'netty-all', version: nettyioVersion
31 | api group: 'io.netty', name: 'netty-transport', version: nettyioVersion
32 | // io.tlf.monkeynetty.test
33 | testImplementation jmeGroup + ':jme3-desktop:' + jmeVersion
34 | testImplementation jmeGroup + ':jme3-lwjgl3:' + jmeVersion
35 | }
36 |
37 |
38 | afterEvaluate {
39 | publishing {
40 | publications {
41 | release(MavenPublication) {
42 | groupId PUBLISH_GROUP_ID
43 | artifactId PUBLISH_ARTIFACT_ID
44 | version PUBLISH_VERSION
45 |
46 | from components.java
47 |
48 | artifact sourcesJar
49 | artifact javadocJar
50 |
51 | pom {
52 | name = PUBLISH_ARTIFACT_ID
53 | description = 'A implementation of a server-client communication system for jMonkeyEngine using Netty.IO that utilizes both TCP and UDP communication.'
54 | url = 'https://github.com/tlf30/monkey-netty'
55 | licenses {
56 | license {
57 | name = 'MIT License'
58 | url = 'https://opensource.org/licenses/MIT'
59 | }
60 | }
61 | developers {
62 | developer {
63 | id = 'tlf30'
64 | name = 'Trevor Flynn'
65 | email = 'trevorflynn@liquidcrystalstudios.com'
66 | }
67 | }
68 | scm {
69 | connection = 'scm:git:git://github.com/tlf30/monkey-netty.git'
70 | developerConnection = 'scm:git:ssh://tlf30/monkey-netty.git'
71 | url = 'https://github.com/tlf30/monkey-netty/'
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/ConnectionListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | /**
28 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
29 | */
30 | public interface ConnectionListener {
31 |
32 | /**
33 | * Called when a client is connected
34 | *
35 | * @param client The client connected.
36 | */
37 | public void onConnect(NetworkClient client);
38 |
39 | /**
40 | * Called when a client disconnects
41 | *
42 | * @param client The client that disconnected.
43 | */
44 | public void onDisconnect(NetworkClient client);
45 | }
46 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/MessageListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
31 | */
32 | public interface MessageListener {
33 |
34 | /**
35 | * When the server/client receives a message, this will be called.
36 | * This is to be implemented by the user code.
37 | *
38 | * @param msg The message received
39 | * @param server The server that sent the message, will be null on client side application
40 | * @param client The client that received the message
41 | */
42 | public void onMessage(NetworkMessage msg, NetworkServer server, NetworkClient client);
43 |
44 | /**
45 | * The listener onMessage will only get called if the message received
46 | * is within this returned list.
47 | *
48 | * @return A list of supported messages by this listener
49 | */
50 | public Class extends NetworkMessage>[] getSupportedMessages();
51 | }
52 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 | package io.tlf.monkeynetty;
25 |
26 | import io.tlf.monkeynetty.msg.NetworkMessage;
27 |
28 | /**
29 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
30 | *
31 | * Used as a basis for building a custom network client.
32 | */
33 | public interface NetworkClient {
34 |
35 | /**
36 | * @return if the client is connected to the server
37 | */
38 | public boolean isConnected();
39 |
40 | /**
41 | * Send a message from the client to the server
42 | *
43 | * @param message The message to send
44 | */
45 | public void send(NetworkMessage message);
46 |
47 | /**
48 | * Internal Use Only
49 | * Called by the server when the server receives a message for the server side connection client.
50 | *
51 | * @param message The message received
52 | */
53 | public void receive(NetworkMessage message);
54 |
55 | /**
56 | * Disconnects the client from the server
57 | */
58 | public void disconnect();
59 |
60 | /**
61 | * @return If the client is connected to the server using SSL
62 | */
63 | public boolean isSsl();
64 |
65 | /**
66 | * @return The address of the server the client is connecting to
67 | */
68 | public String getAddress();
69 |
70 | /**
71 | * @return The port of the server the client is connecting to
72 | */
73 | public int getPort();
74 |
75 | /**
76 | * The service string should be unique to each server.
77 | * This is entirely for user use, and is not validated between server and client.
78 | *
79 | * @return The service the client is connecting to.
80 | */
81 | public String getService();
82 |
83 | /**
84 | * @return Which network protocols the client supports
85 | */
86 | public NetworkProtocol[] getProtocol();
87 |
88 | /**
89 | * Register a message listener with the client.
90 | *
91 | * @param handler The message listener to register
92 | */
93 | public void registerListener(MessageListener handler);
94 |
95 | /**
96 | * Unregister a message listener with the client.
97 | *
98 | * @param handler The message listener to unregister
99 | */
100 | public void unregisterListener(MessageListener handler);
101 |
102 | /**
103 | * Register a connection listener with the client.
104 | *
105 | * @param listener The connection listener to register
106 | */
107 | public void registerListener(ConnectionListener listener);
108 |
109 | /**
110 | * Unregister a connection listener with the client.
111 | *
112 | * @param listener The connection listener to unregister
113 | */
114 | public void unregisterListener(ConnectionListener listener);
115 |
116 | /**
117 | * Set obj value attribute for key param
118 | *
119 | * @param key key for attribute
120 | * @param obj value object for attribute
121 | */
122 | public void setUserData(String key, Object obj);
123 |
124 | /**
125 | * Return attribute stored under key param
126 | *
127 | * @param type
128 | * @param key key for attribute
129 | * @return object casted to T type
130 | */
131 | public T getUserData(String key);
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkMessageDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.buffer.ByteBufInputStream;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
31 | import io.netty.handler.codec.serialization.ClassResolver;
32 |
33 | import java.io.ObjectInputStream;
34 | import java.io.StreamCorruptedException;
35 |
36 | /**
37 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
38 | *
39 | * Decodes a NetworkMessage from a binary stream for recieving to remote side.
40 | * Utilizes NetworkObjectInputtream
41 | *
42 | * Based from: io.netty.handler.codec.serialization.ObjectDecoder
43 | */
44 | public class NetworkMessageDecoder extends LengthFieldBasedFrameDecoder {
45 |
46 | private final ClassResolver classResolver;
47 |
48 | private NetworkRegistrar registrar = new NetworkRegistrar();
49 |
50 | /**
51 | * Creates a new decoder whose maximum object size is {@code 1048576}
52 | * bytes. If the size of the received object is greater than
53 | * {@code 1048576} bytes, a {@link StreamCorruptedException} will be
54 | * raised.
55 | *
56 | * @param classResolver the {@link ClassResolver} to use for this decoder
57 | */
58 | public NetworkMessageDecoder(ClassResolver classResolver) {
59 | this(1048576, classResolver);
60 | }
61 |
62 | /**
63 | * Creates a new decoder with the specified maximum object size.
64 | *
65 | * @param maxObjectSize the maximum byte length of the serialized object.
66 | * if the length of the received object is greater
67 | * than this value, {@link StreamCorruptedException}
68 | * will be raised.
69 | * @param classResolver the {@link ClassResolver} which will load the class
70 | * of the serialized object
71 | */
72 | public NetworkMessageDecoder(int maxObjectSize, ClassResolver classResolver) {
73 | super(maxObjectSize, 0, 4, 0, 4);
74 | this.classResolver = classResolver;
75 | }
76 |
77 | @Override
78 | public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
79 | ByteBuf frame = (ByteBuf) super.decode(ctx, in);
80 | if (frame == null) {
81 | return null;
82 | }
83 |
84 | ObjectInputStream ois = new NetworkObjectInputStream(new ByteBufInputStream(frame, true), classResolver, registrar);
85 | try {
86 | return ois.readObject();
87 | } finally {
88 | ois.close();
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkMessageEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.buffer.ByteBufOutputStream;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import io.netty.handler.codec.MessageToByteEncoder;
31 |
32 | import java.io.NotSerializableException;
33 | import java.io.ObjectOutputStream;
34 | import java.io.Serializable;
35 |
36 | /**
37 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
38 | *
39 | * Encodes a NetworkMessage into a binary stream for sending to remote side.
40 | * Utilizes NetworkObjectOutputStream
41 | *
42 | * Based from: io.netty.handler.codec.serialization.ObjectEncoder
43 | */
44 | public class NetworkMessageEncoder extends MessageToByteEncoder {
45 | private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
46 |
47 | private NetworkRegistrar registrar = new NetworkRegistrar();
48 |
49 | @Override
50 | protected void encode(ChannelHandlerContext ctx, Serializable msg, ByteBuf out) throws Exception {
51 | int startIdx = out.writerIndex();
52 |
53 | ByteBufOutputStream bout = new ByteBufOutputStream(out);
54 | ObjectOutputStream oout = null;
55 | try {
56 | bout.write(LENGTH_PLACEHOLDER);
57 | oout = new NetworkObjectOutputStream(bout, registrar);
58 | oout.writeObject(msg);
59 | oout.flush();
60 | } catch (NotSerializableException nsex) {
61 | throw new NetworkMessageException("Non-Serializable object " + nsex.getMessage() + " found in message " + msg.getClass().getName(), nsex);
62 | } finally {
63 | if (oout != null) {
64 | oout.close();
65 | } else {
66 | bout.close();
67 | }
68 | }
69 |
70 | int endIdx = out.writerIndex();
71 |
72 | out.setInt(startIdx, endIdx - startIdx - 4);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkMessageException.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | /**
28 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.comm
29 | */
30 | public class NetworkMessageException extends RuntimeException {
31 | public NetworkMessageException() {
32 | super();
33 | }
34 |
35 | public NetworkMessageException(String msg) {
36 | super(msg);
37 | }
38 |
39 | public NetworkMessageException(String msg, Throwable cause) {
40 | super(msg, cause);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkObjectInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import io.netty.handler.codec.serialization.ClassResolver;
28 |
29 | import java.io.*;
30 |
31 | /**
32 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
33 | *
34 | * Converts a binary stream into an Object.
35 | * If a class name and UID are sent with the object, this will remember the class to UID relationship.
36 | * All future instances of the UID will be related to the correct class for deserialization.
37 | * Based from: io.netty.handler.codec.serialization.CompactObjectInputStream
38 | */
39 | public class NetworkObjectInputStream extends ObjectInputStream {
40 |
41 | private final ClassResolver classResolver;
42 | private final NetworkRegistrar registrar;
43 |
44 | NetworkObjectInputStream(InputStream in, ClassResolver classResolver, NetworkRegistrar registrar) throws IOException {
45 | super(in);
46 | this.classResolver = classResolver;
47 | this.registrar = registrar;
48 | }
49 |
50 | @Override
51 | protected void readStreamHeader() throws IOException {
52 | int version = readByte() & 0xFF;
53 | if (version != STREAM_VERSION) {
54 | throw new StreamCorruptedException("Unsupported version: " + version);
55 | }
56 | }
57 |
58 | @Override
59 | protected ObjectStreamClass readClassDescriptor()
60 | throws IOException, ClassNotFoundException {
61 | int type = read();
62 | if (type < 0) {
63 | throw new EOFException();
64 | }
65 | switch (type) {
66 | case NetworkObjectOutputStream.TYPE_FAT_DESCRIPTOR:
67 | return super.readClassDescriptor();
68 | case NetworkObjectOutputStream.TYPE_THIN_DESCRIPTOR:
69 | int id = readInt();
70 | String className = registrar.getUidRegistry().get(id);
71 | if (className == null) {
72 | throw new NetworkMessageException("Unregistered type received for decoding: " + id);
73 | }
74 | Class> clazz = classResolver.resolve(className);
75 | return ObjectStreamClass.lookupAny(clazz);
76 | case NetworkObjectOutputStream.TYPE_NEW_DESCRIPTOR:
77 | String newName = readUTF();
78 | int newId = readInt();
79 | registrar.register(newName, newId);
80 | Class> newClazz = classResolver.resolve(newName);
81 | return ObjectStreamClass.lookupAny(newClazz);
82 | default:
83 | throw new StreamCorruptedException("Unexpected class descriptor type: " + type);
84 | }
85 | }
86 |
87 | @Override
88 | protected Class> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
89 | Class> clazz;
90 | try {
91 | clazz = classResolver.resolve(desc.getName());
92 | } catch (ClassNotFoundException ignored) {
93 | clazz = super.resolveClass(desc);
94 | }
95 |
96 | return clazz;
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkObjectOutputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import java.io.*;
28 |
29 | /**
30 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
31 | *
32 | * Converts a Object into a binary stream.
33 | * The first instance of a class sent will send a UID and class name to remote side.
34 | * All future instances of the class sent will only send UID.
35 | * Based from: io.netty.handler.codec.serialization.CompactObjectOutputStream
36 | */
37 | public class NetworkObjectOutputStream extends ObjectOutputStream {
38 |
39 | static final int TYPE_FAT_DESCRIPTOR = 0;
40 | static final int TYPE_THIN_DESCRIPTOR = 1;
41 | static final int TYPE_NEW_DESCRIPTOR = 2;
42 |
43 | private NetworkRegistrar registrar;
44 |
45 | NetworkObjectOutputStream(OutputStream out, NetworkRegistrar registrar) throws IOException {
46 | super(out);
47 | this.registrar = registrar;
48 | }
49 |
50 | @Override
51 | protected void writeStreamHeader() throws IOException {
52 | writeByte(STREAM_VERSION);
53 | }
54 |
55 | @Override
56 | protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
57 | Class> clazz = desc.forClass();
58 | if (!Serializable.class.isAssignableFrom(clazz)) {
59 | throw new NetworkMessageException("Non-Serializable object found: " + clazz.getName());
60 | }
61 | if (clazz.isPrimitive() || clazz.isArray() || clazz.isInterface() ||
62 | desc.getSerialVersionUID() == 0) {
63 | write(TYPE_FAT_DESCRIPTOR);
64 | super.writeClassDescriptor(desc);
65 | } else {
66 | Integer id = registrar.getClassRegistry().get(clazz.getName());
67 | if (id != null) {
68 | write(TYPE_THIN_DESCRIPTOR);
69 | writeInt(id);
70 | } else {
71 | registrar.register(clazz.getName());
72 | write(TYPE_NEW_DESCRIPTOR);
73 | writeUTF(clazz.getName());
74 | writeInt(registrar.getClassRegistry().get(clazz.getName()));
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkProtocol.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | /**
28 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
29 | */
30 | public enum NetworkProtocol {
31 | UDP, TCP
32 | }
33 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkRegistrar.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import java.util.HashMap;
28 |
29 | /**
30 | * NetworkRegistrar keeps a record of class names to UIDs.
31 | * This is used by monkey-netty for transporting objects by using UIDs for each object.
32 | */
33 | public class NetworkRegistrar {
34 |
35 | private HashMap classUID = new HashMap<>();
36 | private HashMap uidClass = new HashMap<>();
37 | private volatile int uid = 0;
38 |
39 | /**
40 | * Register a class with the registrar.
41 | * If attempting to register the same class multiple times, the additional attempts
42 | * to register will be silently ignored.
43 | *
44 | * @param className The fully qualified class name to register
45 | */
46 | public void register(String className) {
47 | if (!classUID.containsKey(className)) {
48 | int newId = uid++;
49 | register(className, newId);
50 | }
51 | }
52 |
53 | /**
54 | * Internal Use Only
55 | * Force a classname and ID pair
56 | *
57 | * @param className The fully qualified class name to register
58 | * @param id The UID of the class
59 | */
60 | public void register(String className, int id) {
61 | classUID.put(className, id);
62 | uidClass.put(id, className);
63 | }
64 |
65 | /**
66 | * @return The registry relating UID to class name
67 | */
68 | public HashMap getUidRegistry() {
69 | return uidClass;
70 | }
71 |
72 | /**
73 | * @return The registry relating class name to UID
74 | */
75 | public HashMap getClassRegistry() {
76 | return classUID;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/NetworkServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Trevor Flynn
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty;
26 |
27 | import io.tlf.monkeynetty.msg.NetworkMessage;
28 |
29 | /**
30 | * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
31 | *
32 | * Used as a basis for building a custom network server.
33 | */
34 | public interface NetworkServer {
35 |
36 | /**
37 | * @return The number of active connections to the server
38 | */
39 | public int getConnections();
40 |
41 | /**
42 | * @return The port number the server is listening on
43 | */
44 | public int getPort();
45 |
46 | /**
47 | * @return If the server is using SSL for TCP transport
48 | */
49 | public boolean isSsl();
50 |
51 | /**
52 | * The service string should be unique to each server.
53 | * This is entirely for user use, and is not validated between server and client.
54 | *
55 | * @return The service the server is running.
56 | */
57 | public String getService();
58 |
59 | /**
60 | * @return Which network protocols the server supports
61 | */
62 | public NetworkProtocol[] getProtocol();
63 |
64 | /**
65 | * @return true if the server is currently blocking new connections
66 | */
67 | public boolean isBlocking();
68 |
69 | /**
70 | * Set if the server should block incoming connections. If true
71 | * the server will close all incoming connections immediately without
72 | * performing a handshake after establishing the connection.
73 | *
74 | * @param blocking If the server should block incoming connections.
75 | */
76 | public void setBlocking(boolean blocking);
77 |
78 | /**
79 | * @return The maximum number of connections the server will allow.
80 | */
81 | public int getMaxConnections();
82 |
83 | /**
84 | * This sets the maximum number of connections the server will be allowed to have at any given time.
85 | * If a connection is attempted to the server and the server currently has the maximum number of
86 | * connections, it will immediately close the connection without performing a handshake after establishing
87 | * the connection.
88 | *
89 | * @param maxConnections The maximum number of connections the server will allow.
90 | */
91 | public void setMaxConnections(int maxConnections);
92 |
93 | /**
94 | * Send a message to all clients connected to the server.
95 | *
96 | * @param message The message to send
97 | */
98 | public void send(NetworkMessage message);
99 |
100 | /**
101 | * Send a message to the provided client
102 | *
103 | * @param message The message to send
104 | * @param client The client to send the message to
105 | */
106 | public void send(NetworkMessage message, NetworkClient client);
107 |
108 | /**
109 | * Register a message listener with the server.
110 | *
111 | * @param handler The message listener to register
112 | */
113 | public void registerListener(MessageListener handler);
114 |
115 | /**
116 | * Unregister a message listener with the server.
117 | *
118 | * @param handler The message listener to unregister
119 | */
120 | public void unregisterListener(MessageListener handler);
121 |
122 | /**
123 | * Register a connection listener with the server.
124 | *
125 | * @param listener The connection listener to register
126 | */
127 | public void registerListener(ConnectionListener listener);
128 |
129 | /**
130 | * Unregister a connection listener with the server.
131 | *
132 | * @param listener The connection listener to unregister
133 | */
134 | public void unregisterListener(ConnectionListener listener);
135 | }
136 |
--------------------------------------------------------------------------------
/monkey-netty/src/main/java/io/tlf/monkeynetty/client/DatagramPacketObjectDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2021 Trevor Flynn
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package io.tlf.monkeynetty.client;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.channel.AddressedEnvelope;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import io.netty.channel.DefaultAddressedEnvelope;
31 | import io.netty.handler.codec.MessageToMessageDecoder;
32 | import io.netty.handler.codec.serialization.ClassResolver;
33 | import io.tlf.monkeynetty.NetworkMessageDecoder;
34 |
35 | import java.net.InetSocketAddress;
36 | import java.util.List;
37 |
38 | public class DatagramPacketObjectDecoder extends MessageToMessageDecoder> {
39 |
40 | private final NetworkMessageDecoder delegateDecoder;
41 |
42 | public DatagramPacketObjectDecoder(ClassResolver resolver) {
43 | this(resolver, Integer.MAX_VALUE);
44 | }
45 |
46 | public DatagramPacketObjectDecoder(ClassResolver resolver, int maxObjectSize) {
47 | delegateDecoder = new NetworkMessageDecoder(maxObjectSize, resolver);
48 | }
49 |
50 | @Override
51 | protected void decode(ChannelHandlerContext ctx, AddressedEnvelope