Giter Club home page Giter Club logo

base64-svg's Introduction

base64-svg

base64 author

Example Usage

see https://etherscan.io/address/0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7#code#L1609

contract Loot is ERC721Enumerable, ReentrancyGuard, Ownable {
  string[] private weapons = [
    'Warhammer',
    'Quarterstaff',
    'Maul',
    'Mace',
    'Club',
    'Katana',
    'Falchion',
    'Scimitar',
    'Long Sword',
    'Short Sword',
    'Ghost Wand',
    'Grave Wand',
    'Bone Wand',
    'Wand',
    'Grimoire',
    'Chronicle',
    'Tome',
    'Book'
  ];

  string[] private chestArmor = [
    'Divine Robe',
    'Silk Robe',
    'Linen Robe',
    'Robe',
    'Shirt',
    'Demon Husk',
    'Dragonskin Armor',
    'Studded Leather Armor',
    'Hard Leather Armor',
    'Leather Armor',
    'Holy Chestplate',
    'Ornate Chestplate',
    'Plate Mail',
    'Chain Mail',
    'Ring Mail'
  ];

  string[] private headArmor = [
    'Ancient Helm',
    'Ornate Helm',
    'Great Helm',
    'Full Helm',
    'Helm',
    'Demon Crown',
    "Dragon's Crown",
    'War Cap',
    'Leather Cap',
    'Cap',
    'Crown',
    'Divine Hood',
    'Silk Hood',
    'Linen Hood',
    'Hood'
  ];

  string[] private waistArmor = [
    'Ornate Belt',
    'War Belt',
    'Plated Belt',
    'Mesh Belt',
    'Heavy Belt',
    'Demonhide Belt',
    'Dragonskin Belt',
    'Studded Leather Belt',
    'Hard Leather Belt',
    'Leather Belt',
    'Brightsilk Sash',
    'Silk Sash',
    'Wool Sash',
    'Linen Sash',
    'Sash'
  ];

  string[] private footArmor = [
    'Holy Greaves',
    'Ornate Greaves',
    'Greaves',
    'Chain Boots',
    'Heavy Boots',
    'Demonhide Boots',
    'Dragonskin Boots',
    'Studded Leather Boots',
    'Hard Leather Boots',
    'Leather Boots',
    'Divine Slippers',
    'Silk Slippers',
    'Wool Shoes',
    'Linen Shoes',
    'Shoes'
  ];

  string[] private handArmor = [
    'Holy Gauntlets',
    'Ornate Gauntlets',
    'Gauntlets',
    'Chain Gloves',
    'Heavy Gloves',
    "Demon's Hands",
    'Dragonskin Gloves',
    'Studded Leather Gloves',
    'Hard Leather Gloves',
    'Leather Gloves',
    'Divine Gloves',
    'Silk Gloves',
    'Wool Gloves',
    'Linen Gloves',
    'Gloves'
  ];

  string[] private necklaces = ['Necklace', 'Amulet', 'Pendant'];

  string[] private rings = [
    'Gold Ring',
    'Silver Ring',
    'Bronze Ring',
    'Platinum Ring',
    'Titanium Ring'
  ];

  string[] private suffixes = [
    'of Power',
    'of Giants',
    'of Titans',
    'of Skill',
    'of Perfection',
    'of Brilliance',
    'of Enlightenment',
    'of Protection',
    'of Anger',
    'of Rage',
    'of Fury',
    'of Vitriol',
    'of the Fox',
    'of Detection',
    'of Reflection',
    'of the Twins'
  ];

  string[] private namePrefixes = [
    'Agony',
    'Apocalypse',
    'Armageddon',
    'Beast',
    'Behemoth',
    'Blight',
    'Blood',
    'Bramble',
    'Brimstone',
    'Brood',
    'Carrion',
    'Cataclysm',
    'Chimeric',
    'Corpse',
    'Corruption',
    'Damnation',
    'Death',
    'Demon',
    'Dire',
    'Dragon',
    'Dread',
    'Doom',
    'Dusk',
    'Eagle',
    'Empyrean',
    'Fate',
    'Foe',
    'Gale',
    'Ghoul',
    'Gloom',
    'Glyph',
    'Golem',
    'Grim',
    'Hate',
    'Havoc',
    'Honour',
    'Horror',
    'Hypnotic',
    'Kraken',
    'Loath',
    'Maelstrom',
    'Mind',
    'Miracle',
    'Morbid',
    'Oblivion',
    'Onslaught',
    'Pain',
    'Pandemonium',
    'Phoenix',
    'Plague',
    'Rage',
    'Rapture',
    'Rune',
    'Skull',
    'Sol',
    'Soul',
    'Sorrow',
    'Spirit',
    'Storm',
    'Tempest',
    'Torment',
    'Vengeance',
    'Victory',
    'Viper',
    'Vortex',
    'Woe',
    'Wrath',
    "Light's",
    'Shimmering'
  ];

  string[] private nameSuffixes = [
    'Bane',
    'Root',
    'Bite',
    'Song',
    'Roar',
    'Grasp',
    'Instrument',
    'Glow',
    'Bender',
    'Shadow',
    'Whisper',
    'Shout',
    'Growl',
    'Tear',
    'Peak',
    'Form',
    'Sun',
    'Moon'
  ];

  function random(string memory input) internal pure returns (uint256) {
    return uint256(keccak256(abi.encodePacked(input)));
  }

  function getWeapon(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'WEAPON', weapons);
  }

  function getChest(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'CHEST', chestArmor);
  }

  function getHead(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'HEAD', headArmor);
  }

  function getWaist(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'WAIST', waistArmor);
  }

  function getFoot(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'FOOT', footArmor);
  }

  function getHand(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'HAND', handArmor);
  }

  function getNeck(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'NECK', necklaces);
  }

  function getRing(uint256 tokenId) public view returns (string memory) {
    return pluck(tokenId, 'RING', rings);
  }

  function pluck(
    uint256 tokenId,
    string memory keyPrefix,
    string[] memory sourceArray
  ) internal view returns (string memory) {
    uint256 rand = random(
      string(abi.encodePacked(keyPrefix, toString(tokenId)))
    );
    string memory output = sourceArray[rand % sourceArray.length];
    uint256 greatness = rand % 21;
    if (greatness > 14) {
      output = string(
        abi.encodePacked(output, ' ', suffixes[rand % suffixes.length])
      );
    }
    if (greatness >= 19) {
      string[2] memory name;
      name[0] = namePrefixes[rand % namePrefixes.length];
      name[1] = nameSuffixes[rand % nameSuffixes.length];
      if (greatness == 19) {
        output = string(
          abi.encodePacked('"', name[0], ' ', name[1], '" ', output)
        );
      } else {
        output = string(
          abi.encodePacked('"', name[0], ' ', name[1], '" ', output, ' +1')
        );
      }
    }
    return output;
  }

  function tokenURI(uint256 tokenId)
    public
    view
    override
    returns (string memory)
  {
    string[17] memory parts;
    parts[
      0
    ] = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style>.base { fill: white; font-family: serif; font-size: 14px; }</style><rect width="100%" height="100%" fill="black" /><text x="10" y="20" class="base">';

    parts[1] = getWeapon(tokenId);

    parts[2] = '</text><text x="10" y="40" class="base">';

    parts[3] = getChest(tokenId);

    parts[4] = '</text><text x="10" y="60" class="base">';

    parts[5] = getHead(tokenId);

    parts[6] = '</text><text x="10" y="80" class="base">';

    parts[7] = getWaist(tokenId);

    parts[8] = '</text><text x="10" y="100" class="base">';

    parts[9] = getFoot(tokenId);

    parts[10] = '</text><text x="10" y="120" class="base">';

    parts[11] = getHand(tokenId);

    parts[12] = '</text><text x="10" y="140" class="base">';

    parts[13] = getNeck(tokenId);

    parts[14] = '</text><text x="10" y="160" class="base">';

    parts[15] = getRing(tokenId);

    parts[16] = '</text></svg>';

    string memory output = string(
      abi.encodePacked(
        parts[0],
        parts[1],
        parts[2],
        parts[3],
        parts[4],
        parts[5],
        parts[6],
        parts[7],
        parts[8]
      )
    );
    output = string(
      abi.encodePacked(
        output,
        parts[9],
        parts[10],
        parts[11],
        parts[12],
        parts[13],
        parts[14],
        parts[15],
        parts[16]
      )
    );

    string memory json = Base64.encode(
      bytes(
        string(
          abi.encodePacked(
            '{"name": "Bag #',
            toString(tokenId),
            '", "description": "Loot is randomized adventurer gear generated and stored on chain. Stats, images, and other functionality are intentionally omitted for others to interpret. Feel free to use Loot in any way you want.", "image": "data:image/svg+xml;base64,',
            Base64.encode(bytes(output)),
            '"}'
          )
        )
      )
    );
    output = string(abi.encodePacked('data:application/json;base64,', json));

    return output;
  }

  function claim(uint256 tokenId) public nonReentrant {
    require(tokenId > 0 && tokenId < 7778, 'Token ID invalid');
    _safeMint(_msgSender(), tokenId);
  }

  function ownerClaim(uint256 tokenId) public nonReentrant onlyOwner {
    require(tokenId > 7777 && tokenId < 8001, 'Token ID invalid');
    _safeMint(owner(), tokenId);
  }

  function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

    if (value == 0) {
      return '0';
    }
    uint256 temp = value;
    uint256 digits;
    while (temp != 0) {
      digits++;
      temp /= 10;
    }
    bytes memory buffer = new bytes(digits);
    while (value != 0) {
      digits -= 1;
      buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
      value /= 10;
    }
    return string(buffer);
  }

  constructor() ERC721('Loot', 'LOOT') Ownable() {}
}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
  bytes internal constant TABLE =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  /// @notice Encodes some bytes to the base64 representation
  function encode(bytes memory data) internal pure returns (string memory) {
    uint256 len = data.length;
    if (len == 0) return '';

    // multiply by 4/3 rounded up
    uint256 encodedLen = 4 * ((len + 2) / 3);

    // Add some extra buffer at the end
    bytes memory result = new bytes(encodedLen + 32);

    bytes memory table = TABLE;

    assembly {
      let tablePtr := add(table, 1)
      let resultPtr := add(result, 32)

      for {
        let i := 0
      } lt(i, len) {

      } {
        i := add(i, 3)
        let input := and(mload(add(data, i)), 0xffffff)

        let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
        out := shl(8, out)
        out := add(
          out,
          and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)
        )
        out := shl(8, out)
        out := add(
          out,
          and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)
        )
        out := shl(8, out)
        out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
        out := shl(224, out)

        mstore(resultPtr, out)

        resultPtr := add(resultPtr, 4)
      }

      switch mod(len, 3)
      case 1 {
        mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
      }
      case 2 {
        mstore(sub(resultPtr, 1), shl(248, 0x3d))
      }

      mstore(result, encodedLen)
    }

    return string(result);
  }
}

License

MIT

base64-svg's People

Contributors

sambacha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.