Toggle navigation
Toggle navigation
This project
Loading...
Sign in
강동현
/
nodejs-game
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
강동현
2021-06-02 22:56:10 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
a4df9d608edd6d84acdf6a4d0a95676bdef8f73a
a4df9d60
1 parent
ae580251
런타임에 메세지 검증
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
133 additions
and
44 deletions
common/dataType.ts
common/message.ts
common/package.json
common/yarn.lock
server/connection/Connection.ts
server/connection/MessageValidator.ts
server/package.json
server/yarn.lock
common/dataType.ts
View file @
a4df9d6
import
{
Boolean
,
Number
,
String
,
Literal
,
Array
,
Tuple
,
Record
,
Union
,
Static
,
}
from
"runtypes"
;
export
const
UserDataRecord
=
Record
({
username
:
String
,
});
export
type
UserData
=
Static
<
typeof
UserDataRecord
>
;
/**
* 방 리스트에서 사용됩니다.
*/
export
interface
RoomDescription
{
uuid
:
string
;
name
:
string
;
currentUsers
:
number
;
maxUsers
:
number
;
}
export
const
RoomDescriptionRecord
=
Record
({
uuid
:
String
,
name
:
String
,
currentUsers
:
Number
,
maxUsers
:
Number
,
});
export
type
RoomDescription
=
Static
<
typeof
RoomDescriptionRecord
>
;
/**
* 방에 접속했을 때 사용됩니다.
*/
export
interface
RoomInfo
{
uuid
:
string
;
name
:
string
;
maxUsers
:
number
;
users
:
UserData
[];
}
export
const
RoomInfoRecord
=
Record
(
{
uuid
:
String
,
name
:
String
,
maxUsers
:
Number
,
users
:
Array
(
UserDataRecord
),
}
);
export
interface
UserData
{
username
:
string
;
}
export
type
RoomInfo
=
Static
<
typeof
RoomInfoRecord
>
;
export
type
Role
=
"drawer"
|
"guesser"
|
"winner"
|
"spectator"
;
...
...
common/message.ts
View file @
a4df9d6
import
{
Role
,
RoomDescription
,
RoomInfo
}
from
"./dataType"
;
import
{
Boolean
,
Number
,
String
,
Literal
,
Array
,
Tuple
,
Record
,
Union
,
Static
,
}
from
"runtypes"
;
import
{
Role
,
RoomDescription
,
RoomDescriptionRecord
,
RoomInfo
,
RoomInfoRecord
,
}
from
"./dataType"
;
// 서버로 들어오는 메세지 타입을 정의합니다.
// 'result' 속성은 서버 요청 결과에만 포함되는 특별한 속성입니다.
interface
ServerInboundMessage
Map
{
export
class
ServerInboundMessageRecord
Map
{
// 로그인을 시도합니다.
login
:
{
username
:
string
;
};
login
=
Record
({
username
:
String
});
// 방 목록을 요청합니다.
roomList
:
{
result
:
RoomDescription
[];
};
roomList
=
Record
(
{
result
:
Array
(
RoomDescriptionRecord
),
}
)
;
// 방에 접속합니다.
joinRoom
:
{
uuid
:
string
;
result
:
RoomInfo
;
};
joinRoom
=
Record
(
{
uuid
:
String
,
result
:
RoomInfo
Record
,
}
)
;
// 방에서 나갑니다.
leaveRoom
:
{}
;
leaveRoom
=
Record
({})
;
// 채팅을 보냅니다.
chat
:
{
message
:
string
;
};
chat
=
Record
(
{
message
:
String
,
}
)
;
// drawer가 단어를 선택합니다.
chooseWord
:
{
word
:
string
;
};
chooseWord
=
Record
(
{
word
:
String
,
}
)
;
// 브러시 정보를 변경합니다.
setBrush
:
{
size
:
number
;
color
:
string
;
drawing
:
boolean
;
};
setBrush
=
Record
(
{
size
:
Number
,
color
:
String
,
drawing
:
Boolean
,
}
)
;
// 브러시를 이동합니다.
moveBrush
:
{
x
:
number
;
y
:
number
;
};
moveBrush
=
Record
(
{
x
:
Number
,
y
:
Number
,
}
)
;
}
type
ServerInboundMessageMap
=
{
[
Key
in
keyof
ServerInboundMessageRecordMap
]:
Static
<
ServerInboundMessageRecordMap
[
Key
]
>
;
};
// 서버에서 나가는 메세지 타입을 정의합니다.
interface
ServerOutboundMessageMap
{
// 방에 접속 중인 유저 목록이 업데이트 되었습니다.
...
...
common/package.json
View file @
a4df9d6
...
...
@@ -3,5 +3,7 @@
"version"
:
"1.0.0"
,
"main"
:
"index.js"
,
"license"
:
"MIT"
,
"dependencies"
:
{}
"dependencies"
:
{
"runtypes"
:
"^6.3.0"
}
}
...
...
common/yarn.lock
View file @
a4df9d6
...
...
@@ -2,3 +2,7 @@
# yarn lockfile v1
runtypes@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/runtypes/-/runtypes-6.3.0.tgz#bd88392c21f471bd45591d5eabaa4644ca7cdf3c"
integrity sha512-FTNUs13CIrCTjReBOaeY/8EY1LYIQVkkwyE9z5MCjZe9uew9/8TRbWF1PcTczgTFfGBjkjUKeedFWU2O3ExjPg==
...
...
server/connection/Connection.ts
View file @
a4df9d6
...
...
@@ -10,12 +10,15 @@ import {
import
{
Room
}
from
"../room/Room"
;
import
{
RoomManager
}
from
"../room/RoomManager"
;
import
{
User
}
from
"../user/User"
;
import
{
MessageValidator
}
from
"./MessageValidator"
;
import
{
SocketWrapper
}
from
"./SocketWrapper"
;
export
class
Connection
{
public
readonly
socket
:
SocketWrapper
;
public
readonly
roomManager
:
RoomManager
;
static
readonly
validator
:
MessageValidator
=
new
MessageValidator
();
public
user
?:
User
;
constructor
(
socket
:
SocketWrapper
,
roomManager
:
RoomManager
)
{
...
...
@@ -38,6 +41,10 @@ export class Connection {
const
type
=
raw
.
type
as
ServerInboundMessageKey
;
const
message
=
raw
.
message
;
if
(
!
Connection
.
validator
.
validate
(
type
,
message
))
{
return
{
ok
:
false
};
}
// 유저 정보가 없으므로 로그인은 따로 핸들링
if
(
type
===
"login"
)
{
return
this
.
handleLogin
(
message
);
...
...
server/connection/MessageValidator.ts
0 → 100644
View file @
a4df9d6
import
{
ServerInboundMessageKey
,
ServerInboundMessageRecordMap
,
}
from
"../../common"
;
import
{
Record
}
from
"runtypes"
;
export
class
MessageValidator
{
private
readonly
messageRecordMap
:
Map
<
ServerInboundMessageKey
,
Record
<
any
,
boolean
>
>
=
new
Map
();
constructor
()
{
const
messageRecordMapContainsResult
=
new
ServerInboundMessageRecordMap
();
for
(
const
key
in
messageRecordMapContainsResult
)
{
const
recordContainsResult
=
messageRecordMapContainsResult
[
key
as
keyof
ServerInboundMessageRecordMap
];
//@ts-ignore because some of entries don't have result property.
this
.
messageRecordMap
.
set
(
key
,
recordContainsResult
.
omit
(
"result"
));
}
}
public
validate
(
key
:
ServerInboundMessageKey
,
message
:
any
)
{
const
messageRecord
=
this
.
messageRecordMap
.
get
(
key
);
if
(
messageRecord
)
{
return
messageRecord
.
validate
(
message
).
success
;
}
return
false
;
}
}
server/package.json
View file @
a4df9d6
...
...
@@ -13,6 +13,7 @@
"mocha"
:
"^8.4.0"
,
"mocha-steps"
:
"^1.3.0"
,
"nodemon"
:
"^2.0.7"
,
"runtypes"
:
"^6.3.0"
,
"socket.io"
:
"^4.1.2"
,
"socket.io-client"
:
"^4.1.2"
,
"ts-node"
:
"^9.1.1"
,
...
...
server/yarn.lock
View file @
a4df9d6
...
...
@@ -1400,6 +1400,11 @@ responselike@^1.0.2:
dependencies:
lowercase-keys "^1.0.0"
runtypes@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/runtypes/-/runtypes-6.3.0.tgz#bd88392c21f471bd45591d5eabaa4644ca7cdf3c"
integrity sha512-FTNUs13CIrCTjReBOaeY/8EY1LYIQVkkwyE9z5MCjZe9uew9/8TRbWF1PcTczgTFfGBjkjUKeedFWU2O3ExjPg==
safe-buffer@5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
...
...
Please
register
or
login
to post a comment