Jump to content

[Share] Captcha Antibot System [Updated 17.6.2011, Version 2] [Please LOCK IT .]


Recommended Posts

Posted

A fixed number of killed mobs to trigger this can be abused, use random numbers instead.

gz

 

nice share btw :)

Posted

Great share it is working very good, only problem I see is the UPPERCASE letters, is that anyway to make it uppercase or lowercase or even mixed.

It was a lot of players in jail today in my server, most of then for mistakes on the typing, they used lowercase instead. Lot of players got pissed off.

 

Also:

When I used a Dreadnought as a gm and it killed lots of mobs at the same time the window keep changing the code and then sometimes it stop with no code at all. I don't know if a regular char will be able to reproduce that but maybe it they kill 49 mobs and then kill 3 more in one hit (50, 51 and 52) it might happen.

Let me know if the fix above will fix that problem.

 

 

Im sorry coz i havent answered, im also using aoe farming on my pack, 10 mobs per rush impact, and yes it getting more than 50 mobs (for example), but it shows to player only one html (atleast the last one), you can make it with tries if you want to, for example to have 3 times to write it wrong and then punish him, about the UPPERCASE and lowercase letters, check this, it is on L2Attackable after my patch :)!

+		   // Suggestions ----------------------------------------------------------------------
+		   // i removed 1 and l and i because there are confusing to users...
+		   // Z, z, and N also get confusing when rotated
+		   // 0, O, and o are also confusing...
+		   // lowercase G looks a lot like a 9 so i killed it
+		   // this should ideally be done for every language...
+		   // i like controlling the characters though because it helps prevent confusion
+		   // So recommended chars are:
+		   // String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
+		   // Suggestions ----------------------------------------------------------------------
+		   String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYZ";
+		   char[] chars = elegibleChars.toCharArray();
+

 

 

Just change ""ABCDEFGHJKLMPQRSTUVWXYZ" to the letters you wanna.

("ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789" are recommented, read the comments, there is reasoning.)

 

Edit: If you want to be sure about html messages and the Mobkill-counter make a check with an output on console :), and check.

Posted

Well first I would suggest the following for the generation of the captcha:

 

	public static BufferedImage generateCaptcha()
{
	final int width = 256;
	final int height = 64;
	final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	final Graphics2D g2d = bufferedImage.createGraphics();
	final Font textFont = new Font("verdana", Font.BOLD, 36);
	final Font textFontUpper = new Font("verdana", Font.BOLD | Font.ITALIC, 36);

	RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
	g2d.setRenderingHints(renderingHints);

	Color textColor = new Color(98, 213, 43);
	Color circleColor = new Color(98, 213, 43);

	int charsToPrint = 5;
	int circlesToDraw = 8;
	float horizMargin = 20.0f;
	double rotationRange = 0.7; // this is radians

	Graphics2D g = (Graphics2D) bufferedImage.getGraphics();

	//Draw an oval
	g.setColor(new Color(30,31,31));
	g.fillRect(0, 0, width, height);

	// lets make some noisey circles
	g.setColor(circleColor);

	for (int i=0; i<circlesToDraw; i++)
	{
		int circleRadius = (int) (Math.random() * height / 2.0);
		int circleX = (int) (Math.random() * width - circleRadius);
		int circleY = (int) (Math.random() * height - circleRadius);
		g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
	}

	g.setColor(textColor);
	g.setFont(textFont);

	FontMetrics fontMetrics = g.getFontMetrics();
	int maxAdvance = fontMetrics.getMaxAdvance();
	int fontHeight = fontMetrics.getHeight();

	// Suggestions ----------------------------------------------------------------------
	// i removed 1 and l and i because there are confusing to users...
	// Z, z, and N also get confusing when rotated
	// 0, O, and o are also confusing...
	// lowercase G looks a lot like a 9 so i killed it
	// this should ideally be done for every language...
	// i like controlling the characters though because it helps prevent confusion
	// So recommended chars are:
	// String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
	// Suggestions ----------------------------------------------------------------------
	String elegibleChars = "abcdefghjijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789";
	char[] chars = elegibleChars.toCharArray();

	float spaceForLetters = -horizMargin * 2 + width;
	float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);

	for (int i=0; i<charsToPrint; i++)
	{
		double randomValue = Math.random();
		int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
		char characterToShow = chars[randomIndex];
		finalString.append(characterToShow);

		// this is a separate canvas used for the character so that
		// we can rotate it independently
		int charWidth = fontMetrics.charWidth(characterToShow);
		int charDim = Math.max(maxAdvance, fontHeight);
		int halfCharDim = (charDim / 2);

		BufferedImage charImage = new BufferedImage(charDim, charDim, BufferedImage.TYPE_INT_ARGB);
		Graphics2D charGraphics = charImage.createGraphics();
		charGraphics.translate(halfCharDim, halfCharDim);
		double angle = (Math.random() - 0.5) * rotationRange;
		charGraphics.transform(AffineTransform.getRotateInstance(angle));
		charGraphics.translate(-halfCharDim,-halfCharDim);
		charGraphics.setColor(textColor);
		charGraphics.setFont(textFont);

		int charX = (int) (0.5 * charDim - 0.5 * charWidth);
		charGraphics.drawString("" + characterToShow, charX,
				((charDim - fontMetrics.getAscent())
						/ 2 + fontMetrics.getAscent()));

		float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
		int y = ((height - charDim) / 2);

		if(Character.isDigit(chars[i]) || Character.isLowerCase(chars[i]))
			g2d.setFont(textFont);
		else
			g2d.setFont(textFontUpper);

		g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);

		charGraphics.dispose();
	}

	g.dispose();

	return bufferedImage;
}

 

And next the following to load it:

 

			final int sId = Config.SERVER_ID;
		int imgId = IdFactory.getInstance().getNextId();

		try
		{
			//File captcha = new File("data/captcha/captcha.png");
			ByteArrayOutputStream bts = new ByteArrayOutputStream();
			ImageIO.write(generateCaptcha(), "png", bts);

			//ImageIO.write(generateCaptcha(), "png", captcha);
			byte[] buffer = bts.toByteArray();
			ByteArrayInputStream bis = new ByteArrayInputStream (buffer, 0, buffer.length);
			PledgeCrest packet = new PledgeCrest(imgId, DDSConverter.convertToDDS(bis).array());
			playerInstance.sendPacket(packet);
		}
		catch (Exception e)
		{
			...

Posted

Well first I would suggest the following for the generation of the captcha:

 

	public static BufferedImage generateCaptcha()
{
	final int width = 256;
	final int height = 64;
	final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	final Graphics2D g2d = bufferedImage.createGraphics();
	final Font textFont = new Font("verdana", Font.BOLD, 36);
	final Font textFontUpper = new Font("verdana", Font.BOLD | Font.ITALIC, 36);

	RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
	g2d.setRenderingHints(renderingHints);

	Color textColor = new Color(98, 213, 43);
	Color circleColor = new Color(98, 213, 43);

	int charsToPrint = 5;
	int circlesToDraw = 8;
	float horizMargin = 20.0f;
	double rotationRange = 0.7; // this is radians

	Graphics2D g = (Graphics2D) bufferedImage.getGraphics();

	//Draw an oval
	g.setColor(new Color(30,31,31));
	g.fillRect(0, 0, width, height);

	// lets make some noisey circles
	g.setColor(circleColor);

	for (int i=0; i<circlesToDraw; i++)
	{
		int circleRadius = (int) (Math.random() * height / 2.0);
		int circleX = (int) (Math.random() * width - circleRadius);
		int circleY = (int) (Math.random() * height - circleRadius);
		g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
	}

	g.setColor(textColor);
	g.setFont(textFont);

	FontMetrics fontMetrics = g.getFontMetrics();
	int maxAdvance = fontMetrics.getMaxAdvance();
	int fontHeight = fontMetrics.getHeight();

	// Suggestions ----------------------------------------------------------------------
	// i removed 1 and l and i because there are confusing to users...
	// Z, z, and N also get confusing when rotated
	// 0, O, and o are also confusing...
	// lowercase G looks a lot like a 9 so i killed it
	// this should ideally be done for every language...
	// i like controlling the characters though because it helps prevent confusion
	// So recommended chars are:
	// String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
	// Suggestions ----------------------------------------------------------------------
	String elegibleChars = "abcdefghjijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789";
	char[] chars = elegibleChars.toCharArray();

	float spaceForLetters = -horizMargin * 2 + width;
	float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);

	for (int i=0; i<charsToPrint; i++)
	{
		double randomValue = Math.random();
		int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
		char characterToShow = chars[randomIndex];
		finalString.append(characterToShow);

		// this is a separate canvas used for the character so that
		// we can rotate it independently
		int charWidth = fontMetrics.charWidth(characterToShow);
		int charDim = Math.max(maxAdvance, fontHeight);
		int halfCharDim = (charDim / 2);

		BufferedImage charImage = new BufferedImage(charDim, charDim, BufferedImage.TYPE_INT_ARGB);
		Graphics2D charGraphics = charImage.createGraphics();
		charGraphics.translate(halfCharDim, halfCharDim);
		double angle = (Math.random() - 0.5) * rotationRange;
		charGraphics.transform(AffineTransform.getRotateInstance(angle));
		charGraphics.translate(-halfCharDim,-halfCharDim);
		charGraphics.setColor(textColor);
		charGraphics.setFont(textFont);

		int charX = (int) (0.5 * charDim - 0.5 * charWidth);
		charGraphics.drawString("" + characterToShow, charX,
				((charDim - fontMetrics.getAscent())
						/ 2 + fontMetrics.getAscent()));

		float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
		int y = ((height - charDim) / 2);

		if(Character.isDigit(chars[i]) || Character.isLowerCase(chars[i]))
			g2d.setFont(textFont);
		else
			g2d.setFont(textFontUpper);

		g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);

		charGraphics.dispose();
	}

	g.dispose();

	return bufferedImage;
}

 

And next the following to load it:

 

			final int sId = Config.SERVER_ID;
		int imgId = IdFactory.getInstance().getNextId();

		try
		{
			//File captcha = new File("data/captcha/captcha.png");
			ByteArrayOutputStream bts = new ByteArrayOutputStream();
			ImageIO.write(generateCaptcha(), "png", bts);

			//ImageIO.write(generateCaptcha(), "png", captcha);
			byte[] buffer = bts.toByteArray();
			ByteArrayInputStream bis = new ByteArrayInputStream (buffer, 0, buffer.length);
			PledgeCrest packet = new PledgeCrest(imgId, DDSConverter.convertToDDS(bis).array());
			playerInstance.sendPacket(packet);
		}
		catch (Exception e)
		{
			...

 

Can you please give us reasoning? As i can see you have changed the font and added all letters/numbers....

Posted

awesome good job man!

 

Question: it is possible if i whant to disable jail and just the character to stay in freezing mode or to disable the if you write also wrong you get jail for 1 minute?

Posted

awesome good job man!

 

Question: it is possible if i whant to disable jail and just the character to stay in freezing mode or to disable the if you write also wrong you get jail for 1 minute?

 

Well, yes, its simple, everywhere you can see this

+                                       activeChar.setPunishLevel(L2PcInstance.PunishLevel.JAIL, 1);

... Just delete it! This is the "method" that jails the player.

Guest
This topic is now closed to further replies.



  • Posts

    • Website: https://l2aurum.com/ Discord: https://discord.gg/ngaD9DJRjE   Dear Players, We are excited to announce that the x300 Summer Season Beta server will open on 19‑06‑2026 at 20:00 GMT+2. As previously mentioned, there will be no wipe and no account deletion. All accounts, characters, items, and progress from Season 1 will remain completely safe. To ensure a fair and competitive start for new players, all Season 1 accounts will be temporarily locked. The official Summer Season launch will take place on 26‑06‑2026 at 20:00 GMT+2. A few weeks after the official launch, Season 1 accounts will be unlocked so previous players can access their characters and continue their journey. This approach allows new players to enjoy a fresh start while preserving the progress and achievements of our long-term community. Thank you for your continued support, and we look forward to welcoming everyone to the new Summer Season. L2Aurum Team   Explore L2 Aurum Features Discover the Enhancements that set us apart!   Information Server Version: Interlude - PvP Server Client Interface: Unique Interface   Rates     Additional Features and changes When you create a new character, you will start in Giran Harbor at Level 1, equipped with full No-Grade items. Auto Farm is available for free for 2 hour daily without VIP. VIP players receive 4 hours of Auto Farm per day. The Auto Farm time resets with the server restart at 5:30 AM. Status Noblesse: Last hit Barakiel. Player Spawn Protection: 7 seconds. Geodata + Pathnodes: Enabled. All commands are available in the Community Board. Maximum 3 Bishops Per Party: Enabled. Boss Protect - Anti-Zerg: Enabled. Shift + click on monsters to see the droplist. Offline shop. Mana Potion Restores 1000 MP with a cooldown of 8 seconds. Inventory Slots: 250.   Weapon Information Lv1 Black Chaotic Weapons. Lv2 Aurum Weapons.   Armor Information Lv1 Blue Apella Armor. Lv2 Aurum Apella Armor. Misc additions Accessories +50 and +150 pdef|mdef. Tattoos: Resolve | Soul | Avadon. Agathions: Cosmetic only (no stats).   Buffs / Dances / Songs / Prophecies Duration: 2 hours. Total Buff Slots: 32 + 4 (Divine Inspiration). Vote Buff: You must vote on 3 of 6 vote sites to get the vote buff blessing. Castle Reward Every clan that captures a castle receives the castle owner clan blessing buff. To receive it, the clan leader must be online.   Events   Raid Bosses Epic Bosses Final Bosses     For full server information please visit website PvP: Server Features   Website: https://l2aurum.com/ Discord: https://discord.gg/ngaD9DJRjE      
    • ⭐ L2Dexter.eu – Interlude x200 The Ultimate PvP Experience 🔥 RATES XP/SP x200 Adena x60 Drop x30 – Spoil x20 Safe Enchant +3 / +4 Armor Max Enchant +16   ⚔️ GAMEPLAY Main Town: Giran NPC Buffer: 3h buffs Auto Loot • Offline Shop • Anti‑Bot Max 5 clients per HWID Unique PvP Zones with rewards Upgraded Armor System Auto Learn Skills • 30+4 Buff Slots Subclass: Free Nobless: Quest or alternative path Shift+Click drop info Global Shout: 7 sec   🏆 OLYMPIAD Cycle: 14 days Hours: 18:00–00:00 GMT+2 Classed & Non‑Classed 1 char per PC   🐉 EPIC BOSSES Baium: 120h Antharas: 192h Valakas: 264h Zaken: 48h AQ: 24h Frintezza: 48h Anakim/Lilith: 56–84h   💠 SOUL CRYSTALS 10→12: Baium/Zaken/Anakim/Lilith 100% 12→13: Valakas/Antharas/Frintezza 100%   🏰 CLAN SYSTEM Max players in epics: 72 Alliances: 3 clans Clan penalty: 1 day Alliance penalty: 2 days Sieges: Clan lvl 6 + rewards   💰 CURRENCIES Vote Coins – Voting Rune +6% P.Def/M.Def, +4% Speed Event Medals – Events, streaming, RB kills Premium Account – Donate, RBs, Top10 NPC Donate Coins – Donate, RBs, competitions
  • Topics

×
×
  • Create New...

Important Information

This community uses essential cookies to function properly. Non-essential cookies and third-party services are used only with your consent. Read our Privacy Policy and We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue..