ป้องกันการโกงผู้เล่นหลายคน


10

ฉันเกือบจะพัฒนาเกมแบบผู้เล่นหลายคนแนวอินดี้เล็กเสร็จแล้ว ในขณะที่ฉันตั้งใจจะอนุญาตให้ผู้คนโกงในผู้เล่นคนเดียวนี่ก็เห็นได้ชัดว่าไม่เป็นที่ยอมรับในผู้เล่นหลายคน ไม่มีใครรู้วิธีที่จะช่วยหยุดค่าเฉลี่ยโจจากการใช้บางอย่างเช่น Cheat-Engine ในการปรับเปลี่ยนบางส่วนของเกม? ขณะนี้ฉันวางแผนที่จะให้ลูกค้าอัปโหลดแฮช MD5 ของแต่ละไฟล์ที่เกมใช้ (เก็บไว้เป็น XML) ไปยังเซิร์ฟเวอร์เกมเพื่อตรวจสอบทุกสองสามวินาที แต่มีอะไรที่ฉันสามารถทำได้เพื่อหยุดสิ่งต่าง ๆ เช่นโปรแกรมแก้ไขหน่วยความจำ ฯลฯ ?


2
ฉันอยากจะแนะนำบทความนี้การสร้างเกมผู้เล่นหลายคน - การรักษาความปลอดภัยที่เขียนขึ้นสำหรับ API แบบผู้เล่นหลายคน แต่ความคิดที่ดีและยังคงมีอยู่
Cyral

คำตอบ:


8

หากคุณกังวลเกี่ยวกับรหัสที่ปรับเปลี่ยนในเครื่องแล้วคุณจะมั่นใจได้อย่างไรว่ามีใครบางคนไม่เพียงแค่แก้ไขรหัสการแจ้งเตือนของคุณเพื่อส่งรายการ MD5 hashes แบบคงที่สิ่งเดียวกับที่คุณคาดหวัง ในความเป็นจริงคุณไม่จำเป็นต้องมีการปรับเปลี่ยนรหัสในการทำเช่นนี้คุณเพียงแค่ต้องใช้พร็อกซีพื้นฐานที่ค่อนข้างพอสมควร (สมมติว่าไม่มี SSL แต่ก็อาจทำให้เสียความพยายามได้อีกเล็กน้อย)

วิธีเดียวที่จะทำสิ่งที่คุณต้องการคือมีเซิร์ฟเวอร์และไม่ไว้วางใจลูกค้าเลย การคำนวณทั้งหมดควรได้รับการจัดการบนเซิร์ฟเวอร์และการกระทำทั้งหมดที่ตรวจสอบแล้วว่าเป็นไปได้ค่อนข้างน้อย ตัวอย่างเช่นไม่อนุญาตให้ลูกค้าบอกว่าพวกเขาต้องการย้ายไปด้านหนึ่งของแผนที่เมื่อคุณรู้ว่าพวกเขาอยู่อีกด้านหนึ่งเมื่อไม่นานมานี้ หากไม่มีเซิร์ฟเวอร์อยู่ตรงกลางทำทุกอย่างที่มีความสำคัญต่อเกมมันเป็นไปไม่ได้ที่จะไม่โกงเพราะคนฉลาดมักจะค้นหาวิธีแก้ไขทุกสิ่งที่คุณสามารถสร้างลงในไคลเอนต์ แม้จะมีสิ่งใดสิ่งหนึ่งมันก็ยังเป็นไปได้ถ้าคุณไม่คิดถึงวิธีการต่าง ๆ ในการจัดการกับสถานการณ์เล็กน้อย ตัวอย่างเช่นการตรวจสอบการเคลื่อนไหวที่ฉันกล่าวถึงก่อนหน้านี้: หากคุณทำแบบง่าย ๆ ในการคำนวณผู้คนอาจจะสามารถเคลื่อนย้ายผ่านกำแพงได้

ดังนั้นคำถามคือค่าเฉลี่ยคือ 'ค่าเฉลี่ยโจ'? คุณได้พูดถึงการแก้ไขรหัสและตัวแก้ไขหน่วยความจำแล้ว นั่นคือสิ่งที่ฉันจะพิจารณาระดับเฉลี่ยโดยส่วนตัวและถ้าคุณต้องการที่จะเป็นกังวลเกี่ยวกับระดับนั้นแล้วเซิร์ฟเวอร์ที่เชื่อถือได้แยกต่างหากซึ่งต้องใช้การยกของหนักทั้งหมดและลูกค้าจะต้มลงไปเป็นอุปกรณ์แสดงผลและอินพุต


2
@ user185812: โดยปกติแล้วควรรออย่างน้อยสองสามชั่วโมงก่อนทำเครื่องหมายคำตอบที่ยอมรับได้ ในขณะที่โดยส่วนตัวแล้วฉันคิดว่าคำตอบของฉันนั้นยอดเยี่ยมมาก (ฉันลำเอียง) แต่คนอื่น ๆ อาจมีความคิดเห็นมากกว่าและการเห็นคำตอบที่ยอมรับได้มักเป็นอุปสรรคต่อผู้อื่นในการตอบ
Matthew Scharley

@ Matthewscharley - ไม่ต้องกังวล ;)
Martin Sojka

11

ลูกค้าอยู่ในมือของศัตรู ( กฎหมายของการออกแบบโลกออนไลน์ )

จริงๆแล้ววิธีเดียวที่จะเอาชนะกลโกงส่วนใหญ่ได้คือให้ลูกค้าเป็น "thin client" นั่นคือ: เพื่อทำหน้าที่เป็นอุปกรณ์อินพุตและเอาต์พุตเท่านั้นและไม่ให้ข้อมูลมากกว่าที่ต้องการ

สิ่งนี้จะไม่หยุดการทำงานอัตโนมัติและสิ่งนี้จะไม่หยุดการรวบรวมและวิเคราะห์ข้อมูลแบบพาสซีฟ แต่คุณสามารถออกแบบเกมของคุณได้ซึ่งสิ่งเหล่านี้จะไม่มีผลกระทบอย่างมีนัยสำคัญ

สิ่งนี้จะไม่หยุดคนที่แฮ็คข้อมูลผ่านข้อความที่ผิดรูปแบบที่เซิร์ฟเวอร์เชื่อถือได้ - ลูกค้าของคุณต้องป้องกันข้อความจากเซิร์ฟเวอร์เช่นเดียวกับที่คุณป้องกันเว็บไซต์ของคุณจากการโจมตีด้วย SQL injection

เนื่องจากคุณต้องการใช้ไคลเอนต์เดียวกันสำหรับเกมที่มีผู้เล่นคนเดียวด้วยเหตุนี้การแก้ปัญหาก็คือการเรียกใช้เซิร์ฟเวอร์ในกระบวนการ / เธรดที่แยกต่างหากและจัดการภายในเป็นการตั้งค่าไคลเอนต์ / เซิร์ฟเวอร์ "กลโกง" จะทำงานบนฝั่งเซิร์ฟเวอร์ Minecraft ทำสิ่งที่คล้ายกันแม้ว่าจะไม่ใช่เกมแรกที่แยกเอ็นจิ้นเกมออกจากส่วนต่อประสานในลักษณะดังกล่าว

การอ่านที่แนะนำ:


2

ในการโกงเกมแบบผู้เล่นหลายคนขั้นพื้นฐานในรูปแบบของ Cheat-Engine จะไม่ทำงาน ลูกค้ากำลังส่งข้อมูลเท่านั้นและการกระทำที่คุณออกแบบไว้ มักจะไม่มากไปกว่าสิ่งที่ผู้เล่น "ทำ" เช่นในทิศทางที่เขากำลังทำงานอยู่ถ้าเขายิงและอื่น ๆ ดังนั้นการเปลี่ยนแปลงที่เขาทำกับหน่วยความจำจะมีผลกับเกมของเขาเท่านั้น แต่ผู้เล่นคนอื่นจะไม่เห็นการเปลี่ยนแปลงที่เรียกว่า desync เกมส่วนใหญ่ตรวจพบ desyncs เช่นนั้นและลบผู้เล่น desynced ออกจากเกม

ขณะนี้ยังมีวิธีการโกงอื่น ๆ แต่ทั้งหมดเกี่ยวกับวิธีการออกแบบเกมของคุณ

เพื่อป้องกันแฮ็กที่ง่ายที่สุดซึ่งปลอมแปลงข้อความเครือข่ายเซิร์ฟเวอร์ควรตรวจสอบแพ็คเกจเหล่านั้นเพื่อหาเหตุผล "ผู้ชายคนนั้นเพิ่งกระโดด 5 หน้าจอ? เป็นไปไม่ได้ปฏิเสธแพ็คเกจ" (โปรดทราบว่าคุณสามารถไปยังเส้นทางที่ซิงโครไนซ์ได้อย่างเต็มที่ - นั่นหมายความว่าทุกอย่างจะซิงโครไนซ์และมีเพียงปุ่ม "ที่เครื่องเล่นกดปุ่ม" - ประเภทของข้อความคือการส่ง - ซึ่งทำให้ข้อความเครือข่ายปลอมแปลง

วิธีสุดท้ายของการโกงในผู้เล่นหลายคนคือความสามารถในการมองเห็นที่แก้ไขลูกค้าเพื่อให้แสดงข้อมูลแก่ผู้เล่นที่เขาไม่ทราบ ตัวอย่างสำหรับสิ่งนี้ไม่แสดงให้เห็นหมอกแห่งสงครามความสามารถในการมองทะลุกำแพงแสดงแผนที่ย่อหรือสิ่งอื่น ๆ สิ่งเหล่านี้ไม่สามารถป้องกันได้


ฉันไม่เห็นด้วยกับการมองเห็นแฮ็ก สิ่งเหล่านี้ไม่สามารถป้องกันได้โดยไม่ให้ข้อมูลลูกค้าจนกว่าตัวละครของพวกเขาจะรับรู้หรือไม่ อย่าเข้าใจฉันผิดนี่อาจไม่ใช่การออกแบบที่ดี แต่นั่นก็ไม่ได้เป็นไปไม่ได้ที่จะป้องกัน
xuincherguixe

@ xuincherguixe ฉันคิดว่ามันเป็นไปไม่ได้ในบางสถานการณ์ ตัวอย่างเช่นลูกค้าทั้งสองกำลังเล่นภายใต้ IP เดียวกันและพอร์ตเดียวกัน ในกรณีเช่นนี้เป็นเพียงความปรารถนาดีของลูกค้าที่ป้องกันไม่ให้เขาอ่านข้อมูลที่มีความหมายต่ออีกฝ่ายหนึ่ง
Wodzu

1

เพื่อป้องกันการแฮ็ก Cheat Engine พื้นฐานที่จัดการค่าตัวแปรของคุณคุณต้องซ่อนค่าเหล่านั้น โดยทั่วไปแล้ว Cheat Engine จะใช้เพื่อระบุตำแหน่งหน่วยความจำของตัวแปรที่น่าสนใจ (พูดจำนวนทองคำหรือชีวิตหรืออัพเกรดระดับความสามารถ) โดยทำการค้นหาค่าที่ทราบของตัวแปรดังกล่าวเล่นเกมมากขึ้นและทำให้ค่าที่ เปลี่ยนแล้ว Cheat Engine จะทำการค้นหาใหม่จากผลลัพธ์ของการค้นหาก่อนหน้าสำหรับค่าใหม่ วิธีนี้ทำให้ผู้โกงสามารถซูมเข้าไปที่ตำแหน่งหน่วยความจำของค่าได้ตอนนี้พวกเขาสามารถเปลี่ยนค่าของตำแหน่งหน่วยความจำนั้นได้โดยใช้ Cheat Engine

ตัวอย่างเช่นฉันมี 245 GOLD ... ด้วย Cheat Engine ฉันค้นหา 245 และค้นหาตำแหน่งหน่วยความจำมากมาย จากนั้นฉันก็เล่นเพิ่มขึ้นและนำทองคำของฉันไปที่ 314 จากนั้นฉันค้นหาผลลัพธ์การค้นหาก่อนหน้าสำหรับค่า 314 และค้นหาตำแหน่งหน่วยความจำที่เก็บทองคำได้อย่างง่ายดาย

วิธีการป้องกันสิ่งนี้คือการไม่เก็บค่าจริงไว้ในตำแหน่งหน่วยความจำ ตัวอย่างเช่นฉันเก็บค่าในวัตถุที่มีการคำนวณมูลค่าตามความต้องการจริงเมื่อมีความจำเป็น สมมุติว่าผู้เล่นมี 245 โกลด์ หากพวกเขาค้นหาตำแหน่งหน่วยความจำที่มีค่า 245 พวกเขาอาจพบจำนวนมาก แต่ไม่มีพวกเขาจะเป็นตำแหน่งหน่วยความจำที่เก็บค่าทองคำจริง ๆ นั่นเป็นเพราะคุณไม่ได้เก็บค่า 245 สำหรับทองคำ เมื่อเกมต้องการทราบจำนวนทองคำมันจะถามวัตถุที่มีค่าสำหรับมันซึ่งจะคำนวณตามความต้องการ

ดังนั้นคำถามในตอนนี้คือ: คุณเก็บค่าไว้ในวิธีที่ไม่เปิดเผยได้อย่างไร? นี่เป็นเรื่องยุ่งยากเล็กน้อยและน่าเกลียดและฉันแน่ใจว่ามีหลายวิธีที่สามารถทำได้ สิ่งที่ฉันชอบทำคือเก็บอาร์เรย์บูลีน (หรืออาร์เรย์ไบต์) ความยาวของอาเรย์สามารถเป็นอะไรก็ได้ แต่สมมุติว่ามันคือ 13 จากนั้นคุณมีตัวนับที่แสดงถึงจำนวน 13 ที่เข้าสู่ค่าจริง ดังนั้นถ้าเราต้องการแทน 245 ตัวนับจะมีค่าเป็น 18 ตอนนี้อาร์เรย์จะมีบูลีนทั้งหมดตั้งค่าเป็นจริงสำหรับส่วนที่เหลือของ 245/13 ... โดยทั่วไปโมดูลัส ในกรณีนี้คือ 11 ดังนั้น 11 บูลีนแรกในอาร์เรย์จะถูกตั้งค่าเป็นจริงส่วนที่เหลือตั้งค่าเป็นเท็จ ในการดึงค่าทั้งหมดที่คุณต้องทำคือคูณตัวนับตามความยาวของอาร์เรย์จากนั้นเพิ่ม 1 สำหรับแต่ละชุดบูลีนเป็นจริง (หยุดที่เท็จแรก) ตอนนี้หมายเลข 245 จะไม่ถูกเก็บไว้ที่ใดและยากที่จะค้นหาตำแหน่งหน่วยความจำที่จะต้องมีการปรับเปลี่ยนปริมาณทองคำ คุณอาจต้องการตั้งค่าความยาวของอาเรย์เป็นขนาดต่าง ๆ (อาจสุ่มเลือกตัวเลขระหว่างช่วงที่เหมาะสมบางอย่าง) เมื่อสร้างวัตถุนี้

แก้ไข: สิ่งนี้มีประโยชน์สำหรับผู้เล่นหลายคนและผู้เล่นเดี่ยว มีการโกงที่สามารถทำได้ในหลายคนซึ่งค่าในแพ็คเก็ตสามารถเปลี่ยนแปลงได้ สิ่งนี้จะต้องใช้เทคนิคต่าง ๆ ในการป้องกันเช่นการเซ็นชื่อแต่ละแพ็คเก็ต


1
โดยทั่วไปเพื่อป้องกันการโกงเกมที่มีผู้เล่นหลายคนจะคำนวณทุกอย่างบนเซิร์ฟเวอร์ดังนั้นการแก้ไขค่าไคลเอนต์หรือในแพ็คเก็ตที่ส่งไปยังเซิร์ฟเวอร์จะไม่เปลี่ยนสิ่งใด ๆ สำหรับเกมจริง แต่ถึงกระนั้นคำตอบที่เหลือก็น่าสนใจ
Vaillancourt

@AlexandreVaillancourt จุดที่ดี ฉันกังวลกับการคำนวณลายเซ็นการคำนวณซีพียูของเซิร์ฟเวอร์ ฉันต้องการรักษาเซิร์ฟเวอร์ให้เร็วโดยเพียงแค่ส่งแพ็คเก็ตระหว่างผู้เล่นสองคน แต่ฉันจะดูอย่างใกล้ชิดทันทีที่คุณชี้ให้เห็น
Jose Martinez

หากคุณส่งอินพุตจากไคลเอนต์ไปยังเซิร์ฟเวอร์เท่านั้นคุณไม่จำเป็นต้องลงชื่อทุกแพ็กเก็ต เมื่ออยู่บนเซิร์ฟเวอร์หากอินพุตไม่เข้าท่าพวกเขาอาจถูกปฏิเสธหรือลูกค้าถูกโกง เซิร์ฟเวอร์จะคำนวณสถานะถัดไปของเกมจากนั้นส่งสถานะใหม่ไปยังผู้เล่นทุกคนนั่นคือวิธีหลีกเลี่ยงการโกง (โดยที่คุณไม่ต้องกำจัดบ็อตแบบนี้ แต่อย่างน้อยคุณก็หลีกเลี่ยงการโกงแบบไม่เป็นทางการ) .
Vaillancourt

1
เพื่อหลีกเลี่ยงปัญหาดังกล่าวคุณปล่อยให้เซิร์ฟเวอร์อัปเดตชีวิตใหม่จากนั้นส่งชีวิตใหม่ไปยังไคลเอนต์ ทุกอย่างถูกคำนวณบนเซิร์ฟเวอร์และปล่อยให้ลูกค้าเป็น "เทอร์มินัลโง่" สำหรับทุกสิ่งที่สำคัญ: ลูกค้าจะต้องรับผิดชอบในการรวบรวมอินพุตจากผู้เล่น ("คลิกที่ x, y ในเวลา T", "hit ปุ่ม X ในเวลา T ") ส่งพวกเขาไปยังเซิร์ฟเวอร์และรับสถานะใหม่จากเซิร์ฟเวอร์ (" ตอนนี้ผู้เล่นอยู่ที่ตำแหน่ง X, Y "," ผู้เล่นมีชีวิต ZZZ ") และแสดงไปยังผู้เล่น
Vaillancourt

1
ด้วยสิ่งนี้สิบแปดมงกุฎ (ชายตรงกลาง) สามารถยุ่งทั้งหมดที่พวกเขาต้องการกับแพ็คเก็ตก็จะไม่เปลี่ยนสถานะของเกมบนเซิร์ฟเวอร์เพราะเซิร์ฟเวอร์จะทำให้แน่ใจว่าการป้อนข้อมูลที่ถูกต้อง ("hmm ลูกค้าได้คลิก ที่ห้าสถานที่ที่แตกต่างกันภายใน 0.03 วินาทีที่ไม่ปกติขอปฏิเสธคลิกเหล่านี้ ") และเรียกใช้ทั้งหมดของการจำลองตัวเอง
Vaillancourt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.