6. Code Arena - asdfgl98/Project-CodeBuddy GitHub Wiki
- ์ฌ์ฉ์๊ฐ ๋ฐฉ์ ์์ฑํ ๋, ๋ฐฉ์ฅ์ธ์ง ์๋ณํ ์ ์๋ ๊ฐ ์์ฑ(room_host)
- ๋ฐฉ์ ์ ์ฅํ ๋ room_host์ ์ ์ฅํ๋ ์ฌ์ฉ์ ์ด๋ฆ์ด ๋์ผํ๋ค๋ฉด ๋ฐฉ์ฅ์ผ๋ก ์ธ์ํฉ๋๋ค.
- ์ฌ์ฉ์๊ฐ ๋ฐฉ์ ์ ์ฅ ์ ์ฌ์ฉ์ ๋ชฉ๋ก ํญ์ ์ถ๊ฐ๋๊ณ ๋ฐฉ์ฅ ์ฌ๋ถ์ ๋ฐ๋ผ '๋ฐฉ์ฅ' ๋๋ '์ผ๋ฐ'์ผ๋ก ๋๋ฉ๋๋ค.
- ๋ฐฉ์ฅ์ ๊ฒ์์ ์์ํ ์์๋ Start ๋ฒํผ์ด ํ์ฑํ๋๊ณ , '์ผ๋ฐ'์ ์ค๋น๋ฅผ ํ ์์๋ Ready ๋ฒํผ์ด ํ์ฑํ ๋ฉ๋๋ค.
๋ฐฉ ์์ฑ์ ์คํ๋๋ ๋ฐฉ์ฅ ๊ถํ ๋ถ์ฌ ์ฝ๋ (ํด๋ผ์ด์ธํธ)
codeArenaList.js (line 65)
arenaSocket.emit("check_admin", { nickname: res.data });
// ๋ฐฉ ์์ฑ์ ๋ฐฉ์ฅ ๊ถํ ๋ถ์ฌ
arenaSocket.on("admin_status", ({ isAdmin }) => {
if (isAdmin) {
arenaSocket["isAdmin"] = isAdmin;
buttonDiv.style.display = "block";
$startBtn.style.display = "block";
}
});
๋ฐฉ ์์ฑ์ ์คํ๋๋ ๋ฐฉ์ฅ ๊ถํ ๋ถ์ฌ ์ฝ๋ (์๋ฒ)
server.js (line 127)
socket.on("check_admin", (nickname) => {
let isAdmin = false;
if (nickname.nickname == roomInfo.createdBy) {
isAdmin = true;
socket["isAdmin"] = true;
} else {
isAdmin = false;
}
socket.emit("admin_status", { isAdmin });
});
์ฌ์ฉ์ ์ ์ฅ ์ ์ฌ์ฉ์ ๋ชฉ๋ก ํญ ์ ๋ฐ์ดํธ ํจ์
codeArenaList.js (line 606)
const updateArenaNickname = (conn_user, room_host, room_number) => {
const $c_a_p_user = document.querySelector(".c_a_p_user");
conn_user.forEach((userInfo) => {
const newUser = document.createElement("div");
if (userInfo.ROOM_NUMBER == room_number) {
if (room_host == userInfo.CONN_USER) {
// ๋ค์ด์ค๋ ์ฌ๋์ด ๋ฐฉ์ ๋ง๋ ์ฌ๋์ ๋๋ค์๊ณผ ๊ฐ๋ค๋ฉด? = ๋ฐฉ์ฅ์ผ ๋
newUser.className = `c_a_p_u1`;
newUser.innerHTML += `
<div class="u_info">
<div class="u_i_img">๋ฐฉ์ฅ</div>
<div class="u_i_nick" data-user="${userInfo.CONN_USER}">${userInfo.CONN_USER}</div>
</div>
<div class="u_remain">
<div div class="u_r_ques">
<div class="u_r_circle ${userInfo.CONN_USER}" style="display:none;">ok</div>
</div>
</div>
`;
$c_a_p_user.append(newUser);
} else {
if (userInfo.USER_READY == "N") {
// ์ค๋น ์ํ์ ๋
// ๋ค์ด์ค๋ ์ฌ๋์ด ๋ฐฉ์ ๋ง๋ ์ฌ๋์ ๋๋ค์๊ณผ ๊ฐ๋ค๋ฉด? = ์ผ๋ฐ์ผ ๋
newUser.className = `c_a_p_u2`;
newUser.innerHTML += `
<div class="u_info">
<div class="u_i_img">์ผ๋ฐ</div>
<div class="u_i_nick normal_user" data-user="${userInfo.CONN_USER}">${userInfo.CONN_USER}</div>
</div>
<div class="u_remain">
<div div class="u_r_ques">
<div class="u_r_circle ${userInfo.CONN_USER}" style="display:none;">READY</div>
</div>
</div>
`;
$c_a_p_user.append(newUser);
} else {
// ๊ธฐ์กด์ ์ค๋นํ๋ ์ฌ๋
// ๋ค์ด์ค๋ ์ฌ๋์ด ๋ฐฉ์ ๋ง๋ ์ฌ๋์ ๋๋ค์๊ณผ ๊ฐ๋ค๋ฉด? = ์ผ๋ฐ์ผ ๋
newUser.className = `c_a_p_u2`;
newUser.innerHTML += `
<div class="u_info">
<div class="u_i_img">์ผ๋ฐ</div>
<div class="u_i_nick normal_user" data-user="${userInfo.CONN_USER}">${userInfo.CONN_USER}</div>
</div>
<div class="u_remain">
<div div class="u_r_ques">
<div class="u_r_circle ${userInfo.CONN_USER}" style="display:block;">READY</div>
</div>
</div>
`;
$c_a_p_user.append(newUser);
}
}
}
});
};
์ ์ฅํ ์ฌ์ฉ์ ๋ฐฉ์ฅ, ์ผ๋ฐ ๊ตฌ๋ถํ์ฌ ์ด๋ฒคํธ ์คํ(์๋ฒ)
server.js(line 390)
if (room_host != nickname) {
ArenaNamespace.to(room_number).emit("enter_normal_user", {
conn_user,
room_host,
room_number,
});
socket.emit("normal_user_ready");
} else {
ArenaNamespace.to(room_number).emit("enter_host_user", {
conn_user,
room_host,
room_number,
});
}
์ ์ฅํ ์ฌ์ฉ์ ๋ฐฉ์ฅ, ์ผ๋ฐ ๊ตฌ๋ถํ์ฌ ์ด๋ฒคํธ ์คํ(ํด๋ผ์ด์ธํธ)
codeArenaList.js(line 570)
arenaSocket.on("enter_host_user", ({ conn_user, room_host, room_number }) => {
const $c_a_p_user = document.querySelector(".c_a_p_user");
const $divs = $c_a_p_user.querySelectorAll("div");
$divs.forEach(($div) => {
$div.remove();
});
// userList๋ ์ ์ฒด ์ ์ ๊ฐ ์
์ฅํ ๋ฐฉ๋ฒํธ์ ๋๋ค์์ ๊ฐ์ฒด๋ก ๋ฐฐ์ด์ ๋ฃ์ ๊ฒ
// room_number๋ ์
์ฅํ๋ ๋ฐฉ์ ๋ฒํธ
// room_host๋ ์
์ฅํ๋ ๋ฐฉ์ ๋ง๋ ์ด
updateArenaNickname(conn_user, room_host, room_number);
});
arenaSocket.on("enter_normal_user", ({ conn_user, room_host, room_number }) => {
const $c_a_p_user = document.querySelector(".c_a_p_user");
const $divs = $c_a_p_user.querySelectorAll("div");
$divs.forEach(($div) => {
$div.remove();
});
updateArenaNickname(conn_user, room_host, room_number);
});
arenaSocket.on("normal_user_ready", () => {
buttonDiv.style.display = "block";
$readyBtn.style.display = "block";
$startBtn.style.display = "none";
});
๋ฐฉ ์์ฑ ๋ฐ ์ ์ฅ.gif
- ๋ฐฉ์ฅ์ด ๊ฒ์์ ์์ํ ์ ์์ต๋๋ค. ํ์ง๋ง ๋ฐฉ์ ์ ์ฅํ ์ฌ์ฉ์ ์ค ๋ฐฉ์ฅ์ ์ ์ธํ ๋ชจ๋ ์ฌ์ฉ์๊ฐ Ready๋ฅผ ํด์ผ ํฉ๋๋ค.
- ๋ฐฉ์ฅ์ ์ ์ธํ ๋ชจ๋ ์ฌ์ฉ์๋ ์ ์ฅํ ๋, Ready ๊ฐ์ด 'N'์ธ ์ํ๋ก DB์ ์ ์ฅ๋ฉ๋๋ค.
- Ready๋ฅผ ํด๋ฆญํ๋ฉด axios๋ฅผ ํตํด DB๋ฅผ ์
๋ฐ์ดํธํ์ฌ ํด๋น ์ฌ์ฉ์์ Ready ๊ฐ์ด 'Y'๋๋ 'N'์ผ๋ก ๋ฐ๋๊ฒ ๋๊ณ ,
๋ชจ๋ ์ธ์์ Ready ๊ฐ์ด 'Y'์ผ ๋ ๋ฐฉ์ฅ์ด Start๋ฒํผ์ ํด๋ฆญํ๋ฉด ๊ฒ์์ด ์์๋ฉ๋๋ค. - axios๋ฅผ ํตํด Start / Ready ๋ฒํผ ํด๋ฆญ ์, DB์ ์ ๊ทผํ์ฌ ๋ชจ๋ ์ฌ์ฉ์์ Ready ๊ฐ์ ์์ ๋ฐ ์กฐํ ํ ํ, ๊ฐ์ ๋ฐ๋ฅธ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
์ผ๋ฐ ์ฌ์ฉ์ ์ค๋น ์๋ฃ/ ์ทจ์ ๊ธฐ๋ฅ
codeArenaList.js (line 330)
// ์ผ๋ฐ ์ฌ์ฉ์ ์ค๋น ์๋ฃ / ์ทจ์ ๊ธฐ๋ฅ
// ๋ ๋ ๋ฒํผ์ ๋๋ ์ ๋ ์คํ๋๋ ํจ์
const ready = () => {
arenaSocket.emit("click_ready_btn", { nickName: currentNickname });
};
// ํด๋ฆญ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฑ๋ก
$readyBtn.addEventListener("click", ready);
// DB์ ์ ๊ทผํ์ฌ Ready ๊ฐ ๋ณ๊ฒฝ
arenaSocket.on("my_ready", (data) => {
axios.post("/codeArena/codeReady", { data }).then((res) => {
let data = JSON.parse(res.data);
arenaSocket.emit("update_ready", data[0]);
});
});
// ์ค๋น / ์ค๋น ์ทจ์ ๊ธฐ๋ฅ
arenaSocket.on("ready_on", (data) => {
let $normal_user = document.querySelectorAll(".normal_user"); // ๋ค์ด์จ ์ผ๋ฐ์ ์ ๋๋ค์ ํ๊ทธ ์ ๋ถ ๊ฐ์ ธ์ค๊ธฐ
let click_nickname = data.nickName; // ํด๋ฆญํ ์ฌ์ฉ์์ ๋๋ค์
let roomNum = data.roomNum; // ํด๋ฆญํ ์ฌ์ฉ์๊ฐ ์ํด์๋ ๋ฐฉ ๋ฒํธ
let isReady = data.isReady;
$normal_user.forEach((user_nick) => {
// user_nick : ๊ฐ ์ผ๋ฐ์ ์ ์ ๋๋ค์
let foreach_nickname = user_nick.dataset.user;
if (isReady == "Y") {
// ์ค๋นX => ์ค๋น
if (click_nickname == foreach_nickname) {
// ํด๋ฆญํ ์ฌ์ฉ์๋ง ํ์ฑํ ํ๊ธฐ์ํด
let ready_on = document.querySelector(`.${foreach_nickname}`);
ready_on.style.display = "block"; // ์ค๋น ํ์ ํ์ฑํ
arenaSocket.emit("ready_count_up"); // ํ์ฌ ์ค๋นํ ์ธ์์+ ์ฒดํฌ
}
} else {
// ์ค๋น => ์ค๋นX
if (click_nickname == foreach_nickname) {
// ํด๋ฆญํ ์ฌ์ฉ์๋ง ํ์ฑํ ํ๊ธฐ์ํด
let ready_on = document.querySelector(`.${foreach_nickname}`);
ready_on.style.display = "none"; // ์ค๋น ํ์ ๋นํ์ฑํ
// ์ฌ๊ธฐ์๋ค๊ฐ DB USER_READY๋ฅผ N๋ก ๋ณ๊ฒฝ
arenaSocket.emit("ready_count_down"); // ํ์ฌ ์ค๋นํ ์ธ์์- ์ฒดํฌ
}
}
});
});
Ready๋ฅผ ํ ์ธ์์ ์นด์ดํธ
codeArenaList.js (line 379)
// Ready ํ ์ธ์์ ์นด์ดํธ
let ready_count;
let currentUsers;
arenaSocket.on("user_count", (user_count) => {
currentUsers = user_count.user_count;
});
arenaSocket.on("ready_count", () => {
axios
.post("/codeArena/readyCount", { roomNum: arenaSocket.roomNum })
.then((res) => {
let arenaUsers = JSON.parse(res.data);
ready_count = arenaUsers[0].COUNT;
});
});
๋ฐฉ์ฅ Start ๋ฒํผ ํด๋ฆญ ๋ก์ง
codeArenaList.js (line 396)
// ๋ฐฉ์ฅ์ด start ๋ฒํผ์ ๋๋ ์ ๋
$startBtn.addEventListener("click", () => {
if (arenaSocket.isAdmin) {
currentUsers = parseInt(currentUsers);
ready_count = parseInt(ready_count);
if (currentUsers - 1 == ready_count) {
arenaSocket.emit("click_start_btn");
$startBtn.style.display = "none";
buttonDiv.style.display = "none";
TIMER();
question_div.style.display = "block";
question_div2.style.display = "block";
}
else { // ์์ ์กฐ๊ฑด ๋ฏธ์ถฉ์กฑ์ผ ๋ ํด๋ฆญ ์ start ๋นจ๊ฐ์ => ํ์์
$startBtn.classList.add("clicked"); // clicked ํด๋์ค ์ถ๊ฐ
setTimeout(() => {
$startBtn.classList.remove("clicked")
}, 500)
}
}
//code editor ๊ธฐ๋ณธ ๊ฐ ์
๋ ฅ
js.setValue(`function codeBuddy(n){
let result;
result = ์ ๋ต์์
๋ ฅํ์ธ์;
return result;
}`);
});
//๋ฐฉ์ฅ์ด Game ์์์ ๋ชจ๋ ์ ์ ready Y -> N ๋ณ๊ฒฝ
arenaSocket.on('gameStart',(roomNum)=>{
axios.post('/codeArena/gameStart', {roomNum})
})
// ๋ฐฉ์ฅ์ด Game ์์์ ๋ชจ๋ ์ ์ ready ํ์ ํด์
arenaSocket.on("remove_ok", () => {
let green_ok = document.querySelectorAll(".u_r_circle")
green_ok.forEach((ok) => {
ok.style.display = "none"
})
})
Start Game.gif
- ์ฃผ์ด์ง ๋ฌธ์ ์ ๋ํด ์๊ณ ๋ฆฌ์ฆ ๋ก์ง์ ์์ฑํ๊ณ , ์ฝ๋ ์คํ์ ํด๋ฆญํ๋ฉด ์คํ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ ๋ฉ๋๋ค.
- ์ฝ๋ ์คํ ํด๋ฆญ ์, axios๋ก '๋ฌธ์ ๋ฒํธ'์ ๋ํ ์ ๋ ฅ๊ฐ๊ณผ ์ถ๋ ฅ๊ฐ(์ ๋ต)์ DB์์ ์๋ต ๋ฐ์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ Code Editor์ ์์ฑํ ์๊ณ ๋ฆฌ์ฆ(value) ๊ฐ์ ๊ฐ์ ธ์์ ์ ๋ ฅ ๊ฐ์ ๋์ ํด ์คํ์ํจ ๊ฒฐ๊ณผ ๊ฐ๊ณผ, ์ถ๋ ฅ ๊ฐ์ ๊ฒ์ฆํด์
- ์ ๋ต ์ ๋ฌด๋ฅผ ํ๋จํ์ฌ iframe์ ์ถ๋ ฅํด์ค๋๋ค.
- ์ฝ๋ ์ ์ถ ํด๋ฆญ ์, ์ฝ๋ ์คํ๊ณผ ๊ฐ์ด ์์ฑํ ์๊ณ ๋ฆฌ์ฆ์ ์คํ์์ผ ๊ฒ์ฆ ํ, ์ ๋ต์ด๋ผ๋ฉด ok ์์ด์ฝ์ด ํ์ฑํ ๋ฉ๋๋ค.
- ๋ฐฉ ์ธ์์ด ๋ชจ๋ ok ์์ด์ฝ์ด ํ์ฑํ ๋์์ ๋, ๊ฒ์์ด ์ข ๋ฃ๋ฉ๋๋ค.
์ฝ๋ ์คํ ๋ฒํผ ํด๋ฆญ์ด๋ฒคํธ
codeArena.js (line 751)
// ์ฝ๋์คํ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
codeStart.addEventListener('click', async(e)=>{
e.preventDefault()
// codeStart ์์ฒญ์ ๋ณด๋ด์ ๋ฌธ์ ๋ฒํธ์ ์ผ์นํ๋ ์
๋ ฅ๊ฐ๊ณผ ์ถ๋ ฅ๊ฐ database์์ ๋ฐํ
const res = await axios.post('/codeArena/codeStart', {jsValue})
.then(res=>{
let data = JSON.parse(res.data)
//์
๋ ฅ๊ฐ
let resultInput = data[0].RESULT_INPUT
//์ถ๋ ฅ๊ฐ
let resultOutput = data[0].RESULT_OUTPUT
// script ํ๊ทธ ์์ฑ
const scriptElement = document.createElement("script");
// ์์ฑํ script ํ๊ทธ์์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ ์ถ๊ฐ
scriptElement.innerHTML = `var n = ${resultInput};
var outPut = ${resultOutput};
${jsValue};
try{
console.log('์ฝ๋์คํ์ค');
if(typeof codeBuddy !== 'undefined'){
if(codeBuddy(n) == outPut){
let data = startResult = '์์ฑํ ํจ์์' + n + '๋ฅผ ๋์
ํ ๊ฒฐ๊ณผ๋ ' + codeBuddy(n) + '์
๋๋ค.'
document.body.innerHTML = '์ ๋ต์
๋๋ค.<br>'+data
}
else{
let data = startResult = '์์ฑํ ํจ์์' + n + '๋ฅผ ๋์
ํ ๊ฒฐ๊ณผ๋ ' + codeBuddy(n) + '์
๋๋ค.'
document.body.innerHTML = 'ํ๋ ธ์ต๋๋ค.<br>'+data
}
}
else {
throw new Error('codeBuddy ํจ์๊ฐ ์ ์๋์ง ์์์ต๋๋ค.');
}
}
catch(err){
console.error('์๋ฌ๋ฐ์',err);
var body = document.body
body.innerHTML = err
body.style.color = 'red'
}
`
// script๋ฅผ body ํ๊ทธ ์์ ์ถ๊ฐ(script๊ฐ ์ ์์๋ํ๊ฒ ํ๊ธฐ์ํจ)
outPut.contentWindow.document.body.appendChild(scriptElement);
})
})
์ฝ๋ ์ ์ถ ๋ฒํผ ํด๋ฆญ์ด๋ฒคํธ
codeArenaList.js (line 805)
// ์ฝ๋์ ์ถ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
codeSubmit.addEventListener('click', async(e)=>{
e.preventDefault()
// codeStart ์์ฒญ์ ๋ณด๋ด์ ๋ฌธ์ ๋ฒํธ์ ์ผ์นํ๋ ์
๋ ฅ๊ฐ๊ณผ ์ถ๋ ฅ๊ฐ database์์ ๋ฐํ
const res = await axios.post('/codeArena/codeStart', {jsValue})
.then(res=>{
let data = JSON.parse(res.data)
//์
๋ ฅ๊ฐ
let resultInput = data[0].RESULT_INPUT
//์ถ๋ ฅ๊ฐ
let resultOutput = data[0].RESULT_OUTPUT
// script ํ๊ทธ ์์ฑ
const scriptElement = document.createElement("script");
// ์์ฑํ script ํ๊ทธ์์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ ์ถ๊ฐ
scriptElement.innerHTML = `
var n = ${resultInput};
var outPut1 = ${resultOutput};
var name = '${currentNickname}';
var startResult;
${jsValue};
try{
if(typeof codeBuddy !== 'undefined'){
if(codeBuddy(n) == outPut1){
let data = startResult = '์์ฑํ ํจ์์' + n + '๋ฅผ ๋์
ํ ๊ฒฐ๊ณผ๋ ' + codeBuddy(n) + '์
๋๋ค.'
let userS = document.querySelectorAll('.u_i_nick')
userS.forEach((user)=>{
if(name == user.dataset.user){
arenaSocket.emit('please', name)
arenaSocket.emit('pleaesRoomNum')
}
})
}
else{
let data = startResult = '์์ฑํ ํจ์์' + n + '๋ฅผ ๋์
ํ ๊ฒฐ๊ณผ๋ ' + codeBuddy(n) + '์
๋๋ค.'
}
}
else {
throw new Error('codeBuddy ํจ์๊ฐ ์ ์๋์ง ์์์ต๋๋ค.');
}
}
catch(err){
console.error('์๋ฌ๋ฐ์',err);
}
`
// script๋ฅผ body ํ๊ทธ ์์ ์ถ๊ฐ(script๊ฐ ์ ์์๋ํ๊ฒ ํ๊ธฐ์ํจ)
document.body.appendChild(scriptElement);
})
})
๋ฌธ์ ์ ๋ต ์ ์คํ๋ก์ง
codeArenaList.js (line 862)
// ์ ๋ต ์ ์ถํ ์ฌ์ฉ์ ok ์์ด์ฝ ํ์ฑํ
arenaSocket.on('testSucess',(data)=>{
let name = data
let check = document.querySelector(`.${data}`)
check.style.display = 'block'
check.innerText = 'ok'
})
// ์ ์ฒด ์ฌ์ฉ์ ๋ชจ๋ ์ ๋ต์ ๊ฒ์ ์ข
๋ฃ
arenaSocket.on('okRoomNum',(data)=>{
let data1 = data.roomNum
axios.post('/codeArena/testSucess',{roomNum:data1, name:currentNickname})
.then(res=>{
let data = JSON.parse(res.data)
data = data.COUNT
if(data == currentUsers){
arenaSocket.emit('gameSet')
}
})
})