코딩기록

항해 81일)오늘의 할 일 + TIL 본문

항해99/TIL

항해 81일)오늘의 할 일 + TIL

뽀짝코딩 2022. 3. 31. 12:02
728x90

 

 

 

 

오늘의 할 일

1. 게임중간에 옵저버가 나갔을때 기존 훈수체팅 횟수로 점수 계산됨

-상태-
나간 옵저버 카운트 0리셋 안되고 포인트 계산 안됨, 남은 팀들 결과창에 나간 옵저버의 정보가 뜸 
겜방에서 대기실로 나간 옵저버 유저디비 state가 계속 남음

​-수정사항-
중간에 나간 옵저버  소켓에서 teachingCnt 0리셋 하기
소켓 disconnecting에서 updateOne- $pull 에서 바꾸면 된다 
겜방에서 대기실로 나간 옵저버 유저디비 state를 endGame으로 변경하기 

-2022-03-31-목 새벽완료

*  소켓 joinGame에서 connect: inGame  변경, disconnecting에서 state:online, connect:outGame 변동되게 했더니

겜중간 새로고침이나 오류등으로 겜소켓 disconnecting 됐다가 connect 됐을때 유저디비 connect에 제대로 inGame이 안찍이로 offline, online등으로 나온다. 그래서 소켓 joinGame에서 connect: inGames → API-gameStart로 변동하고 소켓 disconnecting에서 state:online, connect:outGame에서 API-gameFinishShow에서 변동되게 바꿨다.

 

* 윗 글은 어제 했었던 내용이다 겜방안에 들어가면 유저디비 state는 내가 선택한 player, observer가 저장되고 connect는 inGame으로 뜬다. 중간에 옵저버가나가면 state:online, teachingCnt:0, connect:online 으로 변경되고 그방 게임이 끝나고 계산될때 아무런 영향을 받지 않아야 한다. 근데 화이트 옵저버는 나갔을때 state가 여전이 whiteObserver이고 블랙만 의도한대로 변동 된다. 둘다 똑같은 코드인데 어디서 오류가 났는지 파악해야 한다.

-  해결 - 

와,, 진짜 오타,, ㅜㅜ

소켓 disconnecting에서 오타가 있었다. 

화이트인데 blackTeamObserver로 써서 계속 화이트옵저버가 계산이 안됐었다.  테스트까지 했는데 잘된다. 끝~~~!!

// whiteTeamObserver
    const gameIdW = gameId.whiteTeamObserver
//오타 코드
	// whiteTeamObserver
    const gameIdW = gameId.blackTeamObserver   // blackTeamObserver가 아니라 
    let gameIdWArray = [];                     // whiteTeamObserver이다. 
    const whiteOIds = [];
    for(let i=0; i<gameIdW.length; i++){
      if(gameIdW[i] !== whiteOIds ) {
        gameIdWArray.push(gameIdW[i]);
      }
    }
// 소켓 game방 퇴장 전체코드
socket.on('disconnecting', async () => {
  try {
    const {id, gameNum} = socket.nickname
    
    gameRoom.to(gameNum).emit('bye', socket.id);
    const observerCnt = gameRoomCount(gameNum) - 2; //(-2 플레이어)+(-1 나가는 옵저버)
    // console.log('게임방 소켓 퇴장observerCnt:', observerCnt);
    if (observerCnt) await Rooms.updateOne({ roomNum:gameNum }, { $set: { observerCnt } });
    console.log('게임방 퇴장 소켓 disconnecting🖐️🖐️');
    console.log('게임방 퇴장 소켓,gameNum:', gameNum);
    console.log('게임방 퇴장 소켓,socket.nickname.id:', socket.nickname.id);

    //게임방 퇴장시 (게임 중간에 나감) 옵저버 state변경, connect변경
    const gameId = await Games.findOne({ gameNum }, { _id: 0, blackTeamObserver: 1, whiteTeamObserver: 1 });
    const outObTeachingCnt = await Users.findOne({ id }, { _id: 0, id: 1, teachingCnt: 1 });
    // console.log("457,gameId",gameId) // 457,gameId { blackTeamObserver: [], whiteTeamObserver: [] }
    
    //blackTeamObserver
    const gameIdB = gameId.blackTeamObserver
    let gameIdBArray = [];
    const blackOIds = [];
    for(let i=0; i<gameIdB.length; i++){
      if(gameIdB[i] !== blackOIds ) {
        gameIdBArray.push(gameIdB[i]);
      }
    }
    console.log("게임소켓,gameIdBBBBArray배열안:",gameIdBArray)
    for(let i=0; i<gameIdBArray.length; i++){
      if(gameIdBArray[i] === id && outObTeachingCnt.id === id){
        await Games.updateOne({ gameNum }, { $pull: { blackTeamObserver: id }});
        await Users.updateOne({ id:gameIdBArray[i] }, { $set: { teachingCnt: 0, state: 'online' }});
      }
    }
    // whiteTeamObserver
    const gameIdW = gameId.whiteTeamObserver
    let gameIdWArray = [];
    const whiteOIds = [];
    for(let i=0; i<gameIdW.length; i++){
      if(gameIdW[i] !== whiteOIds ) {
        gameIdWArray.push(gameIdW[i]);
      }
    }
    console.log("게임소켓,gameIdWWWWArray배열안:",gameIdWArray)
    for(let i=0; i<gameIdWArray.length; i++){
      if(gameIdWArray[i] === id && outObTeachingCnt.id === id){
        await Games.updateOne({ gameNum }, { $pull: { whiteTeamObserver: id }});
        await Users.updateOne({ id:gameIdWArray[i] }, { $set: { teachingCnt: 0, state: 'online' }});
      }
    }
  } catch (error) {
    console.log("게임소켓,disconnecting 에러:",error);
  }
});

-게임방 계산 완료됨 220331 22:00-

*게임 중간에 나간 옵저버 teachingCnt, state, connect를 소켓disconnecting에서 게임디비 유저id와 받은 id를 비교해서 바꿔주는데 사실은  disconnecting이벤트에는 내것만 들어오기 때문에 유저디비에 업데이트문만 넣으면 된다.

근데 내가 위처럼 for문으로 한 이유는 내가 3,4종류의 브라우저 창으로 테스트 했을때는 유저디비connect가 제대로 업뎃이 안됐기 때문이었다. 다른 팀원이 '브라우저를 여러개 켜서 그렇다 다른사람들과 하면 괜찮다' 라고 했고 그래서 

await Users.updateOne({ id }, { $set: { state: 'online', connect: 'online' }});

위 코드만 써놓고 다시 여럿이서 테스트를 했는데 그 팀원 말 처럼 유저디비에서 connect가 제대로 업뎃이 됐다.

다른 종류의 브라우저지만 이런 결과가 나온 이유는 잘 모르겠다. 더 알아봐야지.

 

*나간 옵저버의 teachingCnt를 업뎃 하는건 ①. joinGame소켓  ②.로비 connection 두가지 방법이 있는데 ①.방법으로 해서 변경되었다.

 

*API-gameFinishShow에서 옵저버 찾는 내용이 변동되었다.  이미 옵저버키로 여러가지 값을 담아 찾았기 때문에 req.body로 들어온 id가 어느팀 옵저버인지 아는 상황이었다. if (whitO[i].state === 'whiteObserver'){  } 라는 조건문은 필요하지가 않아 if문 빼고 포문만 써서 옵저버 포인트를 계산했더니 결과가 잘 나왔다. 그전에는 gameFinish에서 옵저버 찾는 계산을 result안에 추가로 state값을 넣어  result { win:"user1", state:"whitePlayer"}

req.body로 받은 것과 이긴 플레이어를 비교해서 맞으면 같은팀 옵저버 포인트를 계산하는 걸로 변경 되었다.  

 

2. 퇴장소켓에서  오류 메시지 없애기 teachingCnt, blackTeamPlayer

connect lobby socket e4eexxAavgVfqK9HAAA8
0|server  | 퇴장 errorMessage TypeError: Cannot read properties of null (reading 'blackTeamPlayer')
0|server  |     at module.exports.participantUpdate (/home/ubuntu/Omok-BE/lib/roomSocket/roomOutUpdate.js:26:17)
0|server  |     at runMicrotasks (<anonymous>)
0|server  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)
0|server  |     at async Socket.<anonymous> (/home/ubuntu/Omok-BE/controller/roomSocket.js:153:11)
0|server  | disconnecting: 29.178ms
0|server  | connect lobby socket mpbtkMV5d9aCMxQ-AAA-
0|server  | TypeError: Cannot read properties of null (reading 'length')
0|server  |     at fastPlayer (/home/ubuntu/Omok-BE/controller/lobby.js:167:20)
0|server  |     at runMicrotasks (<anonymous>)
0|server  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)

 

 

-해결-

기존 코드

    await Rooms.updateOne({ roomNum:gameNum }, { $set: { observerCnt } });

바뀐코드

if (observerCnt >= 0) 
    await Rooms.updateOne({ roomNum:gameNum }, { $set: { observerCnt } });

if문을 추가했다.

 

 

 

오늘의 스케줄
  • 11:45 -기상
  • 19:30 - 항해 채용 세션
  •  

 

 

오늘 배운 것

항상 들어오는 값, 보내는 값의 형태 {}, [] 혹은 여러개가 동시에 오는지, 내 것만 오는지 주체를 잘 알아야하고 내가 디비에서 찾은 값이 find, findOne에서 어떤 형태 ( {} or [] )인지 그 키의 밸류가 객체인지 배열인지 구분해서 코드를 작성해야 한다.

보면 코드의 논리도 논리지만 이런 요소들이 코드를 쓸때 가장 헷갈리는 부분이다.

아, 그리고 소켓에서 API로 넘어가는 순서를 프론트에 물어서 알고 있거나 콘솔로 찍어 파악하고 있어야한다. 

복합적으로 생각하고 전체를 파악하는 습관이 중요하다.

 

반응형
Comments