Một bảng xếp hạng chỉ có giá trị khi người đứng đầu thật sự chơi giỏi nhất. Nghe hiển nhiên, nhưng với ứng dụng chạy trên trình duyệt, đây là bài toán khó hơn nhiều người nghĩ: toàn bộ mã của ứng dụng nằm trên máy người chơi, ai đủ kiên nhẫn đều mở ra xem và sửa được. Bài này giải thích máy chủ của AppGiaiTri kiểm một lượt chơi như thế nào, vì sao không có hệ thống nào chặn được gian lận tuyệt đối, và vì sao chúng tôi chọn nói thẳng điều đó thay vì hứa suông. Chúng tôi chỉ mô tả nguyên lý; các ngưỡng cụ thể được giữ kín có chủ ý.
Điều đầu tiên phải chấp nhận: máy người chơi không đáng tin
Ứng dụng web là một đống mã gửi xuống trình duyệt. Người dùng có thể mở công cụ dành cho nhà phát triển, đọc mã, đặt điểm dừng, sửa biến, rồi gửi bất cứ thứ gì lên máy chủ. Mọi thứ nằm trong trình duyệt đều nằm trong tay người chơi.
Từ đó suy ra một hệ quả mà nhiều người làm mới vào nghề không muốn tin: giấu một mã bí mật trong ứng dụng để “ký” kết quả không tạo ra bảo mật thật sự. Nếu ứng dụng tự ký được, người gian lận cũng tự ký được — mã bí mật nằm ngay trong tệp họ đã tải về. Làm rối mã chỉ khiến việc đó tốn thêm vài giờ, không ngăn được. Bản thiết kế của AppGiaiTri ghi rõ điều này thành nguyên tắc, để không ai trong nhóm tốn công vào một ảo giác an toàn.
Vậy máy chủ phải dựa vào những thứ người chơi không sửa được: đồng hồ của chính máy chủ, luật của từng chế độ chơi, và những gì máy chủ tự ghi lại.
Một lượt chơi đi qua máy chủ như thế nào
- Xin số lượt. Khi người chơi bấm bắt đầu, ứng dụng gửi yêu cầu lên máy chủ. Máy chủ cấp một mã lượt chơi duy nhất, một hạt giống ngẫu nhiên (dùng để sắp đặt những thứ ngẫu nhiên trong lượt), và ghi lại thời điểm bắt đầu theo đồng hồ của máy chủ.
- Chơi. Toàn bộ lượt chơi diễn ra trên máy người chơi, không cần liên lạc liên tục với máy chủ. Nhờ vậy ứng dụng vẫn mượt trên mạng yếu.
- Nộp kết quả. Kết thúc, ứng dụng gửi mã lượt chơi kèm kết quả. Máy chủ tìm lại lượt chơi đó, đối chiếu với luật, rồi quyết định: chấp nhận, hay từ chối kèm lý do.
Mấy chi tiết nhỏ ở đây là chỗ khác biệt giữa làm cho có và làm cho đúng:
- Thời lượng do máy chủ tự tính. Ứng dụng không gửi “tôi đã chơi bao lâu”; máy chủ lấy giờ nộp trừ giờ bắt đầu mà nó đã ghi. Phép trừ này còn được làm ngay trong cơ sở dữ liệu, để không bị lệch múi giờ giữa các phần mềm trên máy chủ — một lỗi rất khó thấy, chỉ lộ ra khi có người bị từ chối oan.
- Mỗi lượt chỉ nộp được một lần. Nộp lại cùng mã lượt, máy chủ trả về kết quả cũ và đánh dấu là trùng. Không có chuyện gửi một lượt đẹp mười lần để nhận thưởng mười lần.
- Lượt bị từ chối vẫn được lưu lại, kèm lý do. Nó không lên bảng, nhưng nằm đó để xem xét khi cần.
Máy chủ kiểm những gì
Mỗi ứng dụng, mỗi chế độ chơi có một bộ luật riêng khai báo sẵn trên máy chủ. Bộ luật trả lời mấy câu hỏi đơn giản nhưng hiệu quả:
| Câu hỏi | Chặn được gì |
|---|---|
| Lượt này có ngắn đến mức vô lý không? | Gửi thẳng kết quả mà không chơi, hoặc tua nhanh cả lượt |
| Lượt này có dài đến mức vô lý không? | Mã lượt bị giữ lại hàng giờ để dùng sau |
| Điểm có vượt mức một người chơi được trong ngần ấy thời gian không? | Điểm bị sửa thành con số khổng lồ |
| Điểm có phải là số hợp lệ không? | Điểm âm, điểm không phải số — những thứ có thể làm hỏng cả bảng |
| Với chế độ tính giờ: thời gian báo về có nhanh hơn mức có thể không? | Thành tích bị sửa thấp đi |
| Với chế độ tính giờ: thời gian báo về có dài hơn thời gian thật đã trôi không? | Kết quả tự khai mâu thuẫn với đồng hồ máy chủ |
Điểm tinh tế nằm ở hàng thứ ba: trần điểm không phải một con số cố định mà tỉ lệ với thời lượng của lượt chơi, cộng một khoản dư cho những pha thưởng lớn. Chơi lâu thì được phép có điểm cao; chơi hai mươi giây mà báo điểm của một giờ thì bị từ chối. Mỗi chế độ có tỉ lệ riêng, vì một pha bóng tennis và một trận không chiến sinh điểm với tốc độ rất khác nhau.
Chúng tôi không công bố các ngưỡng này. Không phải vì chúng quá tinh vi, mà vì công bố ngưỡng là chỉ đường cho người gian lận đứng sát ngay dưới vạch.
Những lớp bảo vệ nằm ngoài phép kiểm điểm
Chỉ lượt có số lượt từ máy chủ mới lên bảng
Khi mất mạng, ứng dụng vẫn cho chơi bằng một hạt giống tự tạo trên máy, nhưng lượt đó không có mã từ máy chủ nên không bao giờ lên bảng. Khách chưa đăng nhập cũng được cấp mã lượt, nhưng kết quả chỉ được ghi nhận, không lên bảng. Bảng xếp hạng chỉ dành cho tài khoản thật, với lượt chơi máy chủ đã chứng kiến từ đầu tới cuối.
Trận có hỗ trợ không lên bảng
Người chơi có thể bật hỗ trợ điều khiển hoặc dùng lượt “chơi tiếp” sau khi thua. Những trận đó vẫn được tính tiến độ, nhưng không lên bảng xếp hạng. Đây không phải chống gian lận mà là công bằng: bảng chỉ so những người chơi cùng một điều kiện.
Bảng tách theo phiên bản luật và theo mùa
Mỗi bộ luật mang một tên phiên bản. Khi người làm chỉnh vật lý hay cách tính điểm, bộ luật đổi tên và bảng mới bắt đầu từ đầu, không trộn thành tích của hai kiểu tính khác nhau. Bảng cũng chia theo mùa, nên một thành tích bất thường — dù lọt lưới — không đứng đầu mãi mãi.
Phần thưởng ghi sổ, mỗi thứ chỉ một lần
Điểm kinh nghiệm và huy hiệu được ghi vào một sổ cái chỉ thêm, không sửa, mỗi dòng gắn với đúng một lượt chơi hoặc một huy hiệu. Cơ sở dữ liệu tự từ chối dòng trùng, nên dù ứng dụng có gửi lặp vì mạng chập chờn, phần thưởng cũng không bị cộng hai lần. Điểm kinh nghiệm còn có trần mỗi ngày, để việc cày lượt tự động không đem lại gì nhiều.
Nói thẳng: hệ thống này chặn được gì và không chặn được gì
Những phép kiểm trên chặn được phần lớn gian lận thô: sửa điểm thành con số khổng lồ, gửi kết quả không chơi, gửi lặp lấy thưởng. Đó là loại gian lận phổ biến nhất, vì dễ làm nhất.
Chúng không chặn được một người gian lận tinh vi: sửa điểm vừa đủ cao để nằm trong mức hợp lý, hoặc viết một chương trình tự chơi thay mình. Muốn chặn loại này, máy chủ phải tự chạy lại lượt chơi — nhận toàn bộ chuỗi thao tác của người chơi, dùng cùng hạt giống và cùng bộ luật vật lý, mô phỏng lại từ đầu và so kết quả. Các ứng dụng của AppGiaiTri đã tính vật lý theo bước thời gian cố định và máy chủ đã cấp hạt giống cho từng lượt — đó là nền móng cho việc kiểm lại, dù bước kiểm lại chưa được bật.
Bản thiết kế của hệ thống chia kết quả thành ba mức: chỉ trên máy, đã đồng bộ ở mức thường, và đã xác minh. Hiện tại các bảng xếp hạng đang ở mức thứ hai. Nguyên tắc đi kèm: chừng nào chưa có bước kiểm lại, không quảng bá một bảng nào là tuyệt đối đáng tin.
Không khoá tài khoản chỉ vì một ngưỡng
Mặt trái của mọi hệ thống chống gian lận là bắt oan. Một chiếc điện thoại chậm, đồng hồ lệch, mạng rớt giữa chừng — đều có thể khiến một lượt thật trông đáng ngờ. Vì vậy lượt vượt ngưỡng chỉ bị từ chối khỏi bảng, không kéo theo khoá tài khoản. Nguyên tắc trong bản thiết kế là điểm nghi ngờ cần được người xem xét và người chơi có quyền khiếu nại, tránh khoá hàng loạt chỉ vì một ngưỡng máy.
Câu hỏi thường gặp
Bảng xếp hạng của ứng dụng web có bị gian lận được không?
Có thể, vì mã ứng dụng chạy trên máy người chơi. Máy chủ kiểm thời lượng, trần điểm theo thời gian và tính hợp lệ của kết quả nên chặn được phần lớn gian lận thô, nhưng không hệ thống nào chặn được tuyệt đối nếu chưa tự chạy lại toàn bộ lượt chơi.
Vì sao lượt chơi của tôi không lên bảng xếp hạng?
Thường vì lượt đó chơi lúc mất mạng, bạn chưa đăng nhập, hoặc trận có bật hỗ trợ điều khiển hay dùng lượt chơi tiếp. Cũng có thể điểm đó chưa vượt kỷ lục cũ của bạn, vì bảng chỉ giữ thành tích tốt nhất của mỗi người.
Máy chủ biết tôi chơi bao lâu bằng cách nào?
Máy chủ ghi lại thời điểm bạn bắt đầu lượt theo đồng hồ của chính nó, rồi trừ đi khi bạn nộp kết quả. Ứng dụng không tự khai thời lượng, nên chỉnh đồng hồ điện thoại không thay đổi được con số này.
Bị hệ thống từ chối điểm có bị khoá tài khoản không?
Không. Lượt bị từ chối chỉ không lên bảng và không nhận thưởng; tài khoản và tiến độ của bạn giữ nguyên. Nguyên tắc là không khoá ai chỉ vì một lượt vượt ngưỡng.
Vì sao không công bố luật chống gian lận cụ thể?
Nguyên lý thì công khai, nhưng ngưỡng cụ thể được giữ kín. Công bố ngưỡng chỉ giúp người gian lận chỉnh điểm nằm sát ngay dưới vạch mà không bị phát hiện.
Bảng xếp hạng có được đặt lại không?
Có. Bảng chia theo mùa và theo phiên bản luật chơi; khi cách tính điểm thay đổi, bảng mới bắt đầu từ đầu để mọi người được so trong cùng một điều kiện.