모르는 사람과 채팅하는 게임의 안전장치 만들기
랜선포차의 채팅 보호 모드를 만든 기록. 연락처·링크·만남·개인정보·성적 표현·금전 제안을 메시지째 막고, 띄어쓰기와 한글 숫자 우회를 잡고, 3번이면 3분·5번이면 판 끝까지 채팅을 막는 규칙까지 테스트 문장과 함께 정리했다.

랜선포차는 빠른 매칭 버튼 하나로 모르는 사람 여섯 명이 한 방에 모이는 게임이다. 그리고 그 방에는 자유 채팅이 있다. 게임을 만들면서 가장 오래 붙잡고 있던 문제가 이 채팅이었다. 폭탄 돌리기에서 누가 지든 크게 문제 될 일은 없지만, 모르는 사람이 “카톡 아이디 뭐예요?“라고 묻는 순간은 다르다. 이 글은 그 한 줄이 상대에게 닿지 않게 만든 과정이다.
이모티콘만 쓰게 할까, 채팅을 열까
처음 기획서에는 “랜덤 매칭 방은 이모티콘만”이라고 적혀 있었다. 가장 안전한 방법이다. 막상 게임을 붙여 보니 문제가 있었다. 라이어 게임은 의심을 주고받아야 하고, 금지어 게임은 수다를 떨다 금지어를 말하게 만드는 게임이다. 이모티콘만으로는 게임의 절반이 성립하지 않았다. 결국 모든 방에서 자유 채팅을 열고, 그 대신 채팅이 할 수 없는 일을 정해 두기로 했다.
기준은 “모르는 사람끼리 게임 밖으로 이어지는 통로”였다. 연락처를 주고받거나, 링크로 다른 곳에 부르거나, 만나자고 하거나, 사는 곳과 학교를 묻거나, 성적인 말을 하거나, 돈이나 선물을 주겠다고 하는 말이다. 이 여섯 가지를 “채팅 보호 모드”로 묶었다. 이용 연령도 같은 이유로 정했다. 결정 기록에는 “만 14세 이상 (모르는 사람과 자유 채팅이 있어서)“라고 적혀 있다. 첫 방문 때 나이를 확인하는 화면을 두었다.
| 분류 | 막는 말의 예 | 보낸 사람이 보는 안내 |
|---|---|---|
| 연락처 | 010-XXXX-XXXX, 카톡 아이디 알려줘, 디엠 ㄱ | 연락처·SNS 아이디는 보낼 수 없어요. |
| 링크 | www.example.com, bit.ly/abc, example 닷컴 들어와 | 링크·사이트 주소는 보낼 수 없어요. |
| 만남 | 우리 실제로 만날래?, 주말에 만나자, 우리집 놀러 와 | 따로 만나자는 말은 보낼 수 없어요. |
| 개인정보 | 어디 살아?, 몇 학년이야, 얼굴 보여줘 | 사는 곳·학교 같은 개인정보는 묻지도 말하지도 않기로 해요. |
| 성적 표현 | 성적인 단어, 조건만남 | 그런 말은 보낼 수 없어요. |
| 금전 | 기프티콘 줄게, 용돈 줄게, 계좌 | 돈·선물 주고받는 말은 보낼 수 없어요. |
가리지 않고 아예 보내지 않는다
욕설은 전부터 ♥로 가리고 있었다. 처음에는 보호 모드도 같은 방식으로 문제 되는 부분만 가릴까 생각했다. 그런데 “카톡 ♥♥♥ 알려줘”는 가려도 의도가 그대로 전달된다. 그래서 여섯 가지에 걸린 말은 메시지째 보내지 않기로 했다. 상대 화면에는 아무것도 뜨지 않고, 보낸 사람에게만 노란 안내 한 줄이 뜬다.
판정은 서버가 한다. 폰 쪽 코드는 조작할 수 있기 때문이다. 대신 같은 판정 함수를 클라이언트와 서버가 함께 쓰게 해서, 폰에서도 전송 버튼을 누르기 전에 같은 안내를 먼저 보여 준다. 서버와 폰의 기준이 어긋나 “폰에서는 보내졌다고 떴는데 상대는 못 받는” 일이 없게 하려는 것이다.
우회를 잡는 한 줄 뭉치기
막는 말을 정규식으로 적는 것은 어렵지 않다. 어려운 건 우회다. “카 톡 해”, “공일공 일이삼사 오육칠팔”, “abc123 골뱅이 네이버” 같은 말이 금방 나온다. 그래서 판정 전에 문장을 한 번 “뭉친다”. 글자 모양을 표준형으로 맞추고, 대소문자와 전각·반각 차이를 없애고, 눈에 안 보이는 문자와 사이사이 끼운 기호·공백을 걷어 낸다. 그러면 “카 톡 해”도 “카.톡.해”도 “카톡해”가 된다.
숫자도 비슷하게 다룬다. 한글로 읽어 쓴 숫자는 숫자로 되돌린 뒤, 전화번호처럼 보이는 숫자열이 있으면 연락처로 본다. 다만 “일”, “이” 같은 글자는 평소에도 흔히 쓰는 말이라, 여러 글자가 길게 이어질 때만 숫자로 본다. 게임에 필요한 숫자(업다운, 제로 게임)는 채팅이 아니라 조작판으로 입력하게 만들어 둬서, 채팅에서 긴 숫자를 막아도 게임에는 지장이 없다. 링크는 점과 공백을 벌려 쓰는 식으로 돌려 적어도 알아볼 수 있게 따로 한 번 더 본다. 정확한 기준값은 우회에 쓰일 수 있어서 여기에는 적지 않는다.
막으면 안 되는 말
필터는 막는 것만큼 통과시키는 것이 중요하다. 게임 중에 흔히 나오는 말이 걸리면 채팅이 짜증 나는 기능이 된다. 그래서 테스트에 막아야 할 문장 30개와 통과해야 할 문장 19개를 같이 넣었다.
| 통과해야 하는 말 | 걸릴 뻔한 이유 |
|---|---|
| 가슴이 두근두근 | “가슴”이 성적 표현 목록과 겹침 |
| 사진처럼 멈춰버렸네 | “사진 보내줘”의 사진 |
| 선물 같은 판이었다 | “선물 줄게”의 선물 |
| 고추장 떡볶이 먹고 싶다 | 비속어 약어와 글자가 겹침 |
| 12라운드까지 가자 | 숫자가 들어감 |
| 업다운 25 어때 | 숫자가 들어감 |
그래서 이런 단어는 단독으로 막지 않고, 요청이나 의도가 드러나는 조합일 때만 막는다. 그래도 애매한 경우는 남는다. 이 파일 맨 위 주석에 적어 둔 원칙은 “오탐보다 미탐이 더 위험하다는 쪽으로 기운다”다. 괜찮은 말이 가끔 막히는 불편보다, 연락처가 한 번 새는 쪽이 훨씬 나쁘다. 괜찮은 말이 막혔을 때는 본인에게만 안내가 가고 다시 쓰면 되니, 손해가 작다.
첫 방문 나이 확인(왼쪽)과 만남 제안이 막힌 모습(오른쪽). 대기실에서도 같은 규칙이 적용된다
반복하면 채팅 금지, 그리고 숨기기·신고
한 번 걸린 사람은 실수일 수 있다. 여러 번 걸리는 사람은 다르다. 한 판에 세 번 걸리면 3분 동안, 다섯 번 걸리면 그 판이 끝날 때까지 채팅을 막는다. 막힌 동안에는 “채팅 금지 중이에요. 남은 시간”이 뜨고, 이모티콘은 계속 쓸 수 있다. 방 단위 테스트에서 이 흐름을 그대로 재현했다. “카톡 아이디 알려줘”를 보내면 상대의 채팅 목록은 비어 있고, 이어서 “안녕하세요”는 정상으로 가고, 세 번째로 걸린 뒤에는 멀쩡한 말도 3분 동안 가지 않는지 확인한다.
필터가 모든 불쾌한 말을 잡을 수는 없다. 그래서 사람이 직접 쓰는 도구를 두 개 뒀다. 채팅창에서 상대 이름을 누르면 “채팅 숨기기”와 “신고”가 나온다. 숨기기는 내 화면에서만 그 사람의 말을 안 보이게 한다. 신고는 그 사람의 최근 채팅 최대 10줄을 함께 기록하고, 같은 사람을 같은 판에서 두 번 신고할 수는 없다. 이 기능은 첫날 밤 커밋 0e4ab37에 들어갔고, 신고 기록을 1년이 지나면 자동으로 지우는 처리는 다음 날 커밋 08708bb에 들어갔다. 채팅 내용 자체는 서버에 저장하지 않고, 진행 중인 방의 최근 30줄만 메모리에 두었다가 방이 닫히면 사라진다.
닉네임도 같은 함수로 검사한다. 연락처, 링크, 성적 표현이 들어간 닉네임은 쓸 수 없고, SNS 이름 뒤에 숫자나 영문 아이디가 붙은 모양(“인스타_zzz99”)도 막는다. 이름표가 연락처 광고판이 되는 것을 막기 위해서다.
정규식이 못 하는 것
이 방식에는 한계가 분명하다. 정규식은 문맥을 모른다. 새로운 은어가 생기면 목록을 고쳐야 하고, 아주 교묘하게 돌려 말하면 통과할 수 있다. 그래서 필터를 “완벽한 벽”이 아니라 “첫 번째 문턱”으로 본다. 문턱에서 대부분을 걸러 내고, 넘어온 것은 숨기기와 신고로 사람이 처리하게 했다. 보호 모드가 들어간 커밋 2130138의 메시지에는 이렇게 적혀 있다. “채팅 보호 모드: 연락처·링크·만남·개인정보·성적 표현·금전 제안 차단(우회 포함), 3회 3분·5회 판 끝까지 채팅 금지, 욕설 목록 확대, 닉네임 검사”. 이 목록은 앞으로도 신고 기록을 보며 계속 늘릴 생각이다.
채팅 보호 모드가 켜진 방은 랜선포차 소개 페이지에서 규칙과 함께 볼 수 있다. 같은 방 안에서 다른 사람과 어떻게 만나는지는 빠른 매칭과 친구방 코드에 적었다.


