const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: "*" } });
app.use(express.json());
app.use(express.static('public')); // index.html, withdraw.html is folder mein daal dena
// ==================== DATABASE ====================
// Real app mein MongoDB use karna. Ye demo ke liye hai
let users = {
"user1": { balance: 1000, kyc: true, kycName: "Test User", state: "Maharashtra" }
};
let bankDetails = {}; // { userId: { accNo, ifsc, name, verified: false } }
let pennyDropRequests = {};
let activeRounds = {};
let playerPrices = {
"Virat Kohli": 45, "Bumrah": 40, "Hardik": 38,
"Rohit": 42, "Rashid": 41, "KL Rahul": 39
};
const BLOCKED_STATES = ["Telangana", "Andhra Pradesh", "Assam", "Sikkim", "Nagaland", "Odisha"];
// ==================== MIDDLEWARE ====================
function checkGeoBlock(req, res, next) {
const userId = req.body.userId || req.params.userId;
if (users[userId] && BLOCKED_STATES.includes(users[userId].state)) {
return res.status(403).json({ error: "Tere state mein ye game allow nahi hai" });
}
next();
}
// ==================== WALLET APIs ====================
app.post('/deposit', checkGeoBlock, (req, res) => {
const { userId, amount } = req.body;
// Real mein: Razorpay webhook verify karna yahan
if (!users[userId]) return res.status(400).json({ error: "User nahi mila" });
users[userId].balance += amount;
res.json({ status: "success", newBalance: users[userId].balance });
});
app.post('/save-bank', checkGeoBlock, (req, res) => {
const { userId, accNo, ifsc, name } = req.body;
if (!userId ||!accNo ||!ifsc ||!name) {
return res.status(400).json({ error: "Sab fields bharo" });
}
if (accNo.length < 9 || accNo.length > 18) {
return res.status(400).json({ error: "Account number 9-18 digit ka hona chahiye" });
}
if (!/^[A-Z]{4}0[A-Z0-9]{6}$/.test(ifsc)) {
return res.status(400).json({ error: "IFSC code galat format" });
}
bankDetails[userId] = { accNo, ifsc, name, verified: false };
res.json({ status: "Bank details save ho gaye", data: bankDetails[userId] });
});
app.get('/get-bank/:userId', (req, res) => {
const { userId } = req.params;
res.json({ data: bankDetails[userId] || null });
});
app.post('/initiate-penny-drop', checkGeoBlock, async (req, res) => {
const { userId } = req.body;
if (!bankDetails[userId]) return res.status(400).json({ error: "Pehle bank details save karo" });
if (!users[userId].kyc) return res.status(400).json({ error: "KYC complete karo pehle" });
const { accNo, ifsc, name } = bankDetails[userId];
const utr = 'UTR' + crypto.randomBytes(6).toString('hex').toUpperCase();
// === RAZORPAYX API YAHAN LAGEGA ===
// Demo ke liye maan lete hain success
const nameFromBank = name; // Real mein webhook se aayega
pennyDropRequests[userId] = { utr, nameFromBank, status: "success", amount: 1 };
bankDetails[userId].verified = false;
res.json({ status: "₹1 bhej diya. 2 min mein verify ho jaayega", utr: utr });
});
app.post('/verify-penny-drop', checkGeoBlock, (req, res) => {
const { userId } = req.body;
const request = pennyDropRequests[userId];
const userKycName = users[userId].kycName;
if (!request) return res.status(400).json({ error: "Pehle ₹1 wala request karo" });
if (request.status === "success") {
const bankName = request.nameFromBank.toLowerCase().replace(/\s/g, '');
const kycName = userKycName.toLowerCase().replace(/\s/g, '');
if (bankName === kycName) {
bankDetails[userId].verified = true;
delete pennyDropRequests[userId];
return res.json({ status: "Verified ✅", msg: "Bank account verify ho gaya. Ab withdraw kar sakte ho" });
} else {
bankDetails[userId].verified = false;
return res.status(400).json({
status: "Failed ❌",
msg: `Naam match nahi hua. Bank: ${request.nameFromBank}, KYC: ${userKycName}`
});
}
} else {
res.json({ status: "Pending", msg: "Abhi bank se response nahi aaya. 2 min baad try karo" });
}
});
app.post('/withdraw', checkGeoBlock, (req, res) => {
const { userId, amount } = req.body;
if (!users[userId]) return res.status(400).json({ error: "User nahi mila" });
if (!bankDetails[userId]?.verified) return res.status(400).json({ error: "Bank verify karo pehle" });
if (amount < 100) return res.status(400).json({ error: "Minimum ₹100 withdraw" });
if (users[userId].balance < amount) return res.status(400).json({ error: "Balance kam hai" });
if (!users[userId].kyc) return res.status(400).json({ error: "KYC complete karo pehle" });
let tds = amount > 10000? Math.round(amount * 0.30) : 0;
let finalAmount = amount - tds;
users[userId].balance -= amount;
console.log(`PAYOUT: ₹${finalAmount} to ${bankDetails[userId].name}`);
console.log(`A/C: ${bankDetails[userId].accNo}, IFSC: ${bankDetails[userId].ifsc}, TDS: ₹${tds}`);
res.json({ status: "Withdraw request lag gayi", amount: finalAmount, tds: tds, newBalance: users[userId].balance });
});
// ==================== GAME LOGIC ====================
function startNewRound() {
const roundId = Date.now();
activeRounds[roundId] = { startTime: Date.now(), players: {}, status: "betting" };
setTimeout(() => {
if (activeRounds[roundId]) {
activeRounds[roundId].status = "live";
io.emit('round_live', { roundId });
}
}, 30000);
setTimeout(() => calculateResults(roundId), 180000);
io.emit('new_round', { roundId, playerPrices, timeLeft: 180 });
}
async function calculateResults(roundId) {
const round = activeRounds[roundId];
if (!round) return;
round.status = "ended";
// Real mein: const liveData = await axios.get('https://api.cricapi.com/v1/currentMatches...')
const liveData = {
"Virat Kohli": { runs: Math.floor(Math.random() * 30) },
"Bumrah": { wkts: Math.floor(Math.random() * 3) },
"Hardik": { runs: Math.floor(Math.random() * 25) },
"Rohit": { runs: Math.floor(Math.random() * 25) },
"Rashid": { wkts: Math.floor(Math.random() * 3) },
"KL Rahul": { runs: Math.floor(Math.random() * 20) }
};
let winners = [], maxPoints = -1;
for (let userId in round.players) {
let totalPoints = 0;
round.players[userId].team.forEach(p => {
if (liveData[p]?.runs) totalPoints += liveData[p].runs * 1;
if (liveData[p]?.wkts) totalPoints += liveData[p].wkts * 20;
});
round.players[userId].points = totalPoints;
if (totalPoints > maxPoints) { maxPoints = totalPoints; winners = [userId]; }
else if (totalPoints === maxPoints) { winners.push(userId); }
}
winners.forEach(uid => { if (users[uid]) users[uid].balance += 18; });
io.emit('round_result', { roundId, leaderboard: round.players, winners, liveData });
delete activeRounds[roundId];
startNewRound();
}
io.on('connection', (socket) => {
socket.on('join_round', ({ userId, roundId, team }) => {
if (!users[userId]) return socket.emit('error', 'User nahi mila');
if (BLOCKED_STATES.includes(users[userId].state)) return socket.emit('error', 'Tere state mein ban hai');
if (users[userId].balance < 10) return socket.emit('error', 'Balance kam hai');
if (!users[userId].kyc) return socket.emit('error', 'KYC pending');
if (!activeRounds[roundId] || activeRounds[roundId].status!== 'betting') {
return socket.emit('error', 'Betting band ho gayi');
}
users[userId].balance -= 10;
activeRounds[roundId].players[userId] = { team, points: 0 };
socket.emit('joined_success', { newBalance: users[userId].balance });
});
});
// ==================== START SERVER ====================
setInterval(startNewRound, 180000);
startNewRound();
server.listen(3000, () => console.log('Server 3000 pe chal raha. Game on!'));
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: "*" } });
app.use(express.json());
app.use(express.static('public')); // index.html, withdraw.html is folder mein daal dena
// ==================== DATABASE ====================
// Real app mein MongoDB use karna. Ye demo ke liye hai
let users = {
"user1": { balance: 1000, kyc: true, kycName: "Test User", state: "Maharashtra" }
};
let bankDetails = {}; // { userId: { accNo, ifsc, name, verified: false } }
let pennyDropRequests = {};
let activeRounds = {};
let playerPrices = {
"Virat Kohli": 45, "Bumrah": 40, "Hardik": 38,
"Rohit": 42, "Rashid": 41, "KL Rahul": 39
};
const BLOCKED_STATES = ["Telangana", "Andhra Pradesh", "Assam", "Sikkim", "Nagaland", "Odisha"];
// ==================== MIDDLEWARE ====================
function checkGeoBlock(req, res, next) {
const userId = req.body.userId || req.params.userId;
if (users[userId] && BLOCKED_STATES.includes(users[userId].state)) {
return res.status(403).json({ error: "Tere state mein ye game allow nahi hai" });
}
next();
}
// ==================== WALLET APIs ====================
app.post('/deposit', checkGeoBlock, (req, res) => {
const { userId, amount } = req.body;
// Real mein: Razorpay webhook verify karna yahan
if (!users[userId]) return res.status(400).json({ error: "User nahi mila" });
users[userId].balance += amount;
res.json({ status: "success", newBalance: users[userId].balance });
});
app.post('/save-bank', checkGeoBlock, (req, res) => {
const { userId, accNo, ifsc, name } = req.body;
if (!userId ||!accNo ||!ifsc ||!name) {
return res.status(400).json({ error: "Sab fields bharo" });
}
if (accNo.length < 9 || accNo.length > 18) {
return res.status(400).json({ error: "Account number 9-18 digit ka hona chahiye" });
}
if (!/^[A-Z]{4}0[A-Z0-9]{6}$/.test(ifsc)) {
return res.status(400).json({ error: "IFSC code galat format" });
}
bankDetails[userId] = { accNo, ifsc, name, verified: false };
res.json({ status: "Bank details save ho gaye", data: bankDetails[userId] });
});
app.get('/get-bank/:userId', (req, res) => {
const { userId } = req.params;
res.json({ data: bankDetails[userId] || null });
});
app.post('/initiate-penny-drop', checkGeoBlock, async (req, res) => {
const { userId } = req.body;
if (!bankDetails[userId]) return res.status(400).json({ error: "Pehle bank details save karo" });
if (!users[userId].kyc) return res.status(400).json({ error: "KYC complete karo pehle" });
});
app.post('/verify-penny-drop', checkGeoBlock, (req, res) => {
const { userId } = req.body;
const request = pennyDropRequests[userId];
const userKycName = users[userId].kycName;
});
app.post('/withdraw', checkGeoBlock, (req, res) => {
const { userId, amount } = req.body;
if (!users[userId]) return res.status(400).json({ error: "User nahi mila" });
if (!bankDetails[userId]?.verified) return res.status(400).json({ error: "Bank verify karo pehle" });
if (amount < 100) return res.status(400).json({ error: "Minimum ₹100 withdraw" });
if (users[userId].balance < amount) return res.status(400).json({ error: "Balance kam hai" });
if (!users[userId].kyc) return res.status(400).json({ error: "KYC complete karo pehle" });
});
// ==================== GAME LOGIC ====================
function startNewRound() {
const roundId = Date.now();
activeRounds[roundId] = { startTime: Date.now(), players: {}, status: "betting" };
}
async function calculateResults(roundId) {
const round = activeRounds[roundId];
if (!round) return;
round.status = "ended";
}
io.on('connection', (socket) => {
socket.on('join_round', ({ userId, roundId, team }) => {
if (!users[userId]) return socket.emit('error', 'User nahi mila');
if (BLOCKED_STATES.includes(users[userId].state)) return socket.emit('error', 'Tere state mein ban hai');
if (users[userId].balance < 10) return socket.emit('error', 'Balance kam hai');
if (!users[userId].kyc) return socket.emit('error', 'KYC pending');
if (!activeRounds[roundId] || activeRounds[roundId].status!== 'betting') {
return socket.emit('error', 'Betting band ho gayi');
}
});
// ==================== START SERVER ====================
setInterval(startNewRound, 180000);
startNewRound();
server.listen(3000, () => console.log('Server 3000 pe chal raha. Game on!'));